Освоюємо Java/Основи
Коментарі
ред.Для того, щоб в тексті програми було легше розібратися іншому програмісту або, навіть, згадати, що до чого через значний проміжок часу, під час створення програми корисно в текст вставляти коментарі. Вони не беруться до уваги компілятором, тож на об'єм скомпільованої програми не впливають і їх можна вставляти будь-де. В Java існує три типи коментарів:
- однорядкові з застосуванням двох похилих рисок (//). Все що йде в рядку після них вважається коментарем.
// це коментар
System.out.println("Вивчаємо коментарі"); // виводимо на екран
- багаторядкові — текст можна вказувати в кілька рядків, також зручно, якщо потрібно усунути кілька рядків тексту під час зневадження програми. Для відкриття коментаря використовується /*, а для закриття */. Все що між ними вважається коментарем. Вкладення багаторядкового коментаря в інший багаторядковий коментар не дозволяється.
/*
Це багаторядковий коментар
System.out.println("Це не буде виведено на екрані");
System.out.println("І це також не буде виведено на екрані");
*/
System.out.println("А це буде виведено");
- для автоматичної генерації документації — розпочинаються символами /** і закінчуються */. Використовуються для додавання додаткової інформації про класи та методи, їх призначення, параметри. На основі даної інформації можна згенерувати документацію по розроблених вами класах та їх методах. Дана документація буде подібною до офіційної документації по класах Java.
Типи даних
ред.Java — строго типізована мова. Тобто, на відміну від, наприклад, PHP в Java потрібно вказувати тип змінної при її оголошенні. В Java є вісім основних (примітивних) типів даних. П'ять із них — цілочисельні (включаючи символьний тип char
), два — дійсні (float
, double
) і один логічний (булевий) тип даних.
Тип | Довжина (в байтах) | Діапазон або набір значень |
---|---|---|
boolean | не визначено | true, false |
byte | 1 | −128..127 |
char | 2 | 0..216−1, або 0..65535 |
short | 2 | −215..215−1, або −32768..32767 |
int | 4 | −231..231−1, або −2147483648..2147483647 |
long | 8 | −263..263−1, або приблизно −9.2·1018..9.2·1018 |
float | 4 | -(2-2−23)·2127..(2-2−23)·2127, або приблизно −3.4·1038..3.4·1038, а також , , NaN |
double | 8 | -(2-2−52)·21023..(2-2−52)·21023, або приблизно −1.8·10308..1.8·10308, а також , , NaN |
Змінні
ред.Оголошення змінних розпочинаються з обов'язкового вказання типу даних, після чого йде назва змінної. Оголошення змінної завершується крапкою з комою, оскільки оголошення в Java вважається інструкцією.
int k;
double salary;
char ourChar;
Назва змінної повинна починатися з букви, далі може бути необмежена кількість цифр та букв. Причому, оскільки в Java використовується Unicode, то змінні можуть бути написані навіть кирилицею, проте в такому разі ваша програма буде важко читабельною для іноземців. В мові враховується регістр символів. Тому K та k — це різні змінні. Не можна використовувати як назви зарезервовані слова. В одному рядку можна оголошувати декілька змінних, проте в такому разі утруднюється читання тексту програми:
int k,i, num;
Ініціалізацію змінної можна здійснити як при оголошенні так і в подальшому в програмі:
int i;
int j=1;
char key;
/* решту ініціалізуємо будь-де в програмі,
бажано ініціалізувати, якомога ближче до місця використання змінної
*/
key='Y';
i=0;
Вибір назви змінної залежить від програміста, проте є кілька рекомендацій, щодо імен. Зокрема, бажано давати змістовні імена. Так, наприклад, якщо ми хочемо позначити кількість студентів, замість s чи ks, краще використати numStudents. Це доволі зручно, коли програма велика і програміст застосовує багато змінних. Змістовні імена таким чином, полегшують роботу з текстом програми як власне творцю програми, так і іншим людям. Саме таке найменування рекомендує Sun (детальніше про рекомендовану систему найменувань: Code Conventions for the Java Programming Language: Naming Conventions). Інколи, деякі програмісти ще вказують тип змінної iNumStudents — змінна типу int, cKey — змінна типу char і т.д., (так звана w:Угорська нотація, була популярна у Microsoft у минулому столітті). Недоліком такого запису є те, що при приведенні змінної до іншого типу, назва може не відповідати змісту.
В Java 10 можна оголошувати локальну змінну із вказанням типу var (local variable), що можна використовувати, коли із присвоюваного явно відомо тип змінної.
var num=10;
var str="Your string";
Однією з переваг var є те, що це дозволяє дещо скоротити запис при використанні довгих назв типів об'єктних змінних (див. розділи про класи та об'єкти). var не рекомендується використовувати, коли із рядка коду не очевидно явно тип даних змінної, якій присвоюється значення.
Оператори
ред.Оператор (англ. operator) - це спеціальний символ, який повідомляє транслятору про те, що ви хочете виконати операцію з деякими операндами (наприклад, +,-,%, <<). Зазвичай, мови програмування визначають набір опера́торів, подібних до операторів в математиці. В певному сенсі, оператори є спеціальними функціями. Окрім арифметичних дій, оператори в мовах програмування можуть виконувати операції на логічних значеннях, операції з рядками. Оператори порівняння можуть використовуватись для перевірки рівності двох значень. На відміну від функцій, оператори є базовими діями мови програмування, їх назва коротша, та, як правило, складається із спеціальних символів.
Оператори виконують відповідні операції над операндами (наприклад, додавання). Деякі оператори вимагають одного операнда, їх називають унарними. Одні знаки операції ставляться перед операндами і називаються префіксними, інші – після, тоді вони називаються постфіксними. Більшість же операторів ставляться між двома операндами, такі оператори називаються інфіксними бінарними операторами.
Java надає багате операторами середовище. Більшість операторів можна поділити на 4 групи: арифметичні, розрядні(бітові), відношення, логічні(булеві). Інколи окремо виділяють ще оператори присвоєння, представники якої є у всіх інших групах. Також Джава визначає деякі додаткові оператори, які застосовуються в певних специфічних ситуаціях, наприклад instanceof (перевіряє приналежність об'єкта до певного класу). Існує тернарний оператор, що працює з трьома операндами (?:).
Слід зауважити щодо термінології. У літературі, що можна знайти у нашій країні, операторами інколи називають окремі види інструкцій (англ statement, досл. твердження, вираз), як то цикли та умовні інструкції, а то й просто функції. Саме слово operator відповідно заміняють словом операція. Часто різнобій в перекладах зустрічається в різних частинах однієї книги, що пов'язано з низькою якістю перекладів ряду книг, різнобоєм в англо-українських та англо-російських словниках, різноманітністю термінології в різних мовах програмування та неоднозначністю перекладу з англійської. В даній книзі дотримуватиметься термінологія, яка також зустрічається в нашій перекладній літературі, однозначніша і наближена до англомовного оригіналу термінології мови Java, тобто: operator —- оператор, statement —- інструкція.
Арифметичні оператори
ред.Арифметичні оператори використовуються в математичних виразах так само як і в алгебрі і представлені в таблиці.
Оператор | Операція | Оператор | Операція |
---|---|---|---|
+ | Додавання | += | Додавання з присвоєнням |
- | Віднімання (а також унарний мінус) | -= | Віднімання з присвоєнням |
* | Множення | * = | Множення з присвоєнням |
/ | Ділення | /= | Ділення з присвоєнням |
% | Залишок ділення по модулю | %= | Залишок ділення по модулю з присвоєнням |
++ | Інкремент (збільшення на 1) | -- | Декремент (зменшення на 1) |
Оператор мінус крім віднімання дозволяє поміняти знак операнда (з додатнього на від’ємний і навпаки). Коли операція ділення застосовується для цілочислових операндів, то дробова частина результату відкидається.
В наступній програмі подана робота з основними арифметичними операторами.
public class MathOp {
public static void main(String args[]) {
int k;
int a = 25;
int b = 15;
k = a + b;
System.out.println("Сума: а + b = " + k);
System.out.println("Добуток: a * b = " + a * b);
System.out.println("Результат ділення цілочисельних: а / b = " + a / b); //дробова частина відкидається
System.out.println("Залишок по модулю: a % b = " + a % b);
}
}
Операнди арифметичних операторів повинні бути чисельних типів. Ви не можете використовувати їх для операндів булевого типу. Проте їх можна застосовувати з типом char, оскільки тип char по суті є підмножиною типу int.
Інкремент та декремент
ред.Серед арифметичних операторів необхідно виділити оператори інкременту(збільшення на 1) і декременту (зменшення на 1). Доволі часто доводиться збільшувати певне значення змінної на одиницю. Вираз на зразок х=х+1 можна записати за допомогою оператора інкременту х++. Аналогічно із зменшенням на одиницю х--.
Дані оператори можуть бути як префіксними та і постфіксними. І тут потрібно бути уважним при їхньому використанні. Так, наприклад маємо:
int x = 50;
у = х++;
В результаті у = 50, а не 51, як можна б було подумати. Суть в тому, що спочатку відбувається присвоєння у значення х, а згодом х буде збільшене на 1. Щоб значення змінної було еквівалентне інструкціям:
х = х + 1;
y = x;
необхідно записати вираз так:
y = ++x;
Аналогічно і з декрементом.
Порозрядні оператори
ред.Java визначає ряд порозрядних (побітових) операторів, що можуть застосовуватися до цілочисельних типів, long, int, short, char та byte. Ці оператори виконують дії над окремими розрядами(бітами) їхніх операндів. Наступна таблиця наводить список даних операторів:
Оператор | Опис | Оператор | Опис |
---|---|---|---|
~ | Порозрядне одномістне НІ (NOT) | & | Порозрядне І (AND) |
| | Порозрядне АБО (OR) | ^ | Порозрядне виняткове АБО (ХOR) |
>> | Зсув вправо | >>> | Зсув вправо із заповненням нулями |
<< | Зсув вліво | &= | Порозрядне І (AND) з присвоєнням |
|= | Порозрядне АБО (OR) з присвоєнням | ^= | Порозрядне виняткове АБО (XOR) з присвоєнням |
>>= | Зсув вправо з присвоєнням | >>>= | Зсув вправо з заповненням нулями і присвоєнням |
Десяткове | Двійкове | Шістнадцяткове |
---|---|---|
0 | 0000 | 0 |
1 | 0001 | 1 |
2 | 0010 | 2 |
3 | 0011 | 3 |
4 | 0100 | 4 |
5 | 0101 | 5 |
6 | 0110 | 6 |
7 | 0111 | 7 |
8 | 1000 | 8 |
9 | 1001 | 9 |
10 | 1010 | A |
11 | 1011 | B |
12 | 1100 | C |
13 | 1101 | D |
14 | 1110 | E |
15 | 1111 | F |
Розуміння роботи порозрядних операцій тісно пов’язане з двійковим представлення чисел у комп’ютері. Більш того двійковий формат є основою цифрової техніки. Тому розуміння двійкової системи числення і порозрядних операцій доволі необхідне програмістам. Маніпулювання з розрядами доволі часто необхідне при роботі з зображеннями та апаратним обладнанням.
Насамперед, розглянемо як представляються звичайні десяткові числа у двійковому форматі. Принцип представлення такий же як десятковий, лише з тією різницею, що замість 10 цифр (0-9) у двійковій системі є лише дві (0 та 1). Так, наприклад, число 53 буде мати вигляд 00110101. Число представляється через позиції одиничок. Щоб перевести двійкове число у десяткову систему, достатньо двійку піднести до степеня позиції одиниці починаючи з 0. Тобто для 00110101 маємо 2^0+2^2+ 2^4+ 2^5= 1+4+16+32=53. Також можна здійснити обернене переведення шляхом ділення на 2. Взагалі це доволі значна тема. Операціям в двійковій системі числення і власне самій двійковій системі присвячено доволі багато математичної та технічної літератури. Якщо Вас цікавить це, то можете звернутися до такої літератури, ми ж не будемо вдаватися у всі деталі, а лише розглянемо те, що потрібне для розуміння роботи операторів Java. Якщо ви не знайомі з правилами переведення, то можете скористатися комп'ютерним калькулятором.
Слід зазначити, що часто в програмуванні застосовують 16-ву систему числення для представлення чисел. В 16-й системі числення застосовують цифри 0-9 та літери від A-F. Причиною є те, що її набагато легше переводити в двійкову систему числення і простіше в програмі написати 16-ве число ніж двійкове. Тобто програмісту менше друкувати знаків і менша вірогідність помилки при друці числа. Так, наприклад, число 255 в двійковій системі числення буде 11111111, а в 16-й FF, 10-1010-A, 78 - 0100 1110 -4E.
Двійкові від’ємні числа представляються шляхом інвертування усіх розрядів і додавання одиниці. Тобто: 11001010 +00000001 =11001011 (-53).
Причиною доповнення на одиницю є те, що при інвертуванні нуля 00000000 отримуємо 11111111. В існування двох нулів немає сенсу, а додавання одиниці дозволяє усунути цю проблему, оскільки тоді отримуємо 100000000 одержуємо 9-ти розрядне число, при використання 8-ми розрядного типу даних відбувається переповнення розрядності і одиниця спереду відкидається. Аналогічно при більшій розрядності (16,32,64). Крім того, перший розряд в числах – це знаковий. Тому доволі часто в мовах програмування крім звичайних цілочисельних типів є типи unsighned (безнакові). Такі типи дозволяють помістити у змінну більше по модулю число. Так, якщо в звичайно змінну byte можна вмістити числа від -128..127 то в беззнакову змінну можна вмістити числа від 0...255.
Порозрядні логічні оператори
ред.Порозрядні логічні оператори це &, |, ^ та ~. Зауважте, що порозрядні операції виконуються над усім операндом, але окремо над кожним розрядом. Наступна таблиця демонструє результат застосування операторів. Тут А та B операнди над якими виконується відповідна операція.
A | B | A | B | A & B | A ^ B | ~A |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 0 | 1 | 0 |
0 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 0 |
Для прикладу розглянемо порозрядне АБО, яке представлене оператором |, якщо хоч один операнд є одиницею, то результат буде 1. Так, якщо застосуємо до наступних чисел оператор АБО:
A | 0101 |
B | 1011 |
A|B | 1111 |
Наступний приклад демонструє застосування оператора АБО в програмі:
class BitLogic {
public static void main(String args[]) {
String binary[] = {
"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
};
int a = 3; // 0 + 2 + 1 або 0011 в двійковому коді
int b = 6; // 4 + 2 + 0 або 0110 в двійковому коді
int c = a | b;
System.out.println(" a = " + binary[a]);
System.out.println(" b = " + binary[b]);
System.out.println(" a|b = " + binary[c]);
}
}
Результат:
a = 0011 b = 0110 a|b = 0111
В наведеному вище прикладі введений масив binary[] для того, щоб вивести результат в двійковій системі числення. Масиви - це набір однотипних елементів, для звернення до елементів масиву необхідне вказання номера елементу починаючи з нуля, наприклад, binary[8], що і відбувається в інструкції:
System.out.println(" a|b = " + binary[c]);.
Якщо ми просто виведемо число:
System.out.println(" a|b = " + c);
то результат буде виведено в десятковій системі.
Робота з масивами буде розглянута в наступних розділах.
Аналогічна робота і з іншими порозрядними операторами. Для того, щоб легше було запам’ятати таблицю істинності операторів, можна скористатись наступним прийомом: операцію АБО можна умовно прирівняти до операції додавання(лише що стосується окремих розрядів). Таким чином, якщо у нас два нуля то буде нуль, якщо хоча б один розряд одиниця, то матимемо одиницю. Застосування оператора &, можна уявляти як здійснення операції множення. Справді, якщо Ви подивитися таблицю, то побачимо що одиниця отримується коли обидва біти дорівнюють 1, якщо ж хоч один операнд рівний нулю, то результат теж 0. Виключне АБО — достатньо запам’ятати, що різниться лише від звичайного АБО при двох одиницях. Ну, а з оператором НІ взагалі проблем немає. Він просто інвертує значення на протилежне.
Оператор АБО доволі корисний, якщо необхідно встановити певний розряд в одиницю, а & корисний коли необхідне обнулення певного розряду. Так, якщо необхідно встановити третій розряд з кінця в одиницю, нам не потрібно знати інші розряди:
A | 1010 |
B | 0100 |
A|B | 1110 |
С | 0111 |
A&С | 0010 |
Оператори відношення
ред.Оператори відношення (також називають операторами порівняння) визначають відношення одного операнду до іншого. Зокрема, вони визначають рівність та впорядкування операндів. Дані оператори наведені в таблиці.
Оператор | Опис |
---|---|
== | Рівно |
!= | Не рівно |
> | Більше |
< | Менше |
>= | Більше рівне |
<= | Менше рівне |
Результатом операції порівняння є результат типу boolean із значеннями true або false. Найчастіше оператори відношення використовуються у виразах, що застосовуються в умовних інструкціях (IF) та у циклах.
Оператори рівно (==) та не рівно (!=) можна застосовувати практично зі всіма типами. Хоча є і свої нюанси такого порівняння для певних типів. Зверніть увагу, що оператор порівняння складається з двох знаків дорівнює, лише в такому разі здійснюється порівняння операндів. З одним знаком – це оператор присвоєння. Оператори впорядкування (більше, менше) можна застосовувати лише до числових типів, як то цілі та дійсні числа.
Зауважте, що на відміну від С/С++, в Java не можна записати інструкцію на зразок:
int thing = 0;
if (!thing) ….. // можливе в С++, але не в Java
для Java необхідно записати:
if (thing != 0) ……
Причиною є інший принцип організації true та false. В С++ true — будь-яка ненульова величина, а false – це нуль. В Java true та false мають нецифрові значення. Тому в таких випадках необхідне застосування операторів відношення.
Булеві логічні оператори
ред.Булеві логічні оператори застосовуються для операндів типу boolean, результатом є булева величина
Оператор | Опис |
---|---|
& | Логічне І (AND) |
| | Логічне АБО (OR) |
^ | Логічне виняткове АБО (XOR) |
|| | Коротке АБО |
&& | Коротке І |
! | Логічне одиничне НІ (NOT) |
&= | І з присвоєнням |
|= | АБО з присвоєнням |
^= | Виняткове АБО з присвоєнням |
== | Рівність |
!= | Не рівність |
?: | Тернарний if-then-else (якщо-тоді-інакше) |
Оператори булевої логіки &,|,^ оперують над булевими значеннями подібно до того як аналогічні порозрядні оператори над бітами.
A | B | A | B | A & B | A ^ B | !A |
---|---|---|---|---|---|
False | False | False | False | False | True |
True | False | True | False | True | False |
False | True | True | False | True | True |
True | True | True | True | False | False |
Якщо ви запам'ятали таблицю істинності порозрядних операторів, то дана таблиця аналогічна, лише замість 1 та 0 маємо true та false. Унарний оператор НІ тут позначається знаком !. Як і в порозрядних операціях — інвертує значення: !True=False !False=True.
Наступна программа демонструє використання логічних булевих операторів.
class BoolLogic {
public static void main(String args[]) {
boolean a = true;
boolean b = false;
boolean c = a | b;
boolean d = a & b;
boolean e = a ^ b;
boolean f = (!a & b) | (a & !b);
boolean g = !a;
System.out.println(" a = " + a);
System.out.println(" b = " + b);
System.out.println(" a | b = " + c);
System.out.println(" a & b = " + d);
System.out.println(" a ^ b = " + e);
System.out.println("!a & b | a & !b = " + f);
System.out.println(" !a = " + g);
}
}
Результат:
a = true b = false a | b = true a & b = false a ^ b = true !a & b | a & !b = true !a = false
Два короткі оператори АБО(||) та І(&&) дозволяють здійснити перевірку першої частини і якщо вона не вірна (false), то друга частина виразу не буде розглядатися. Такі оператори мають сенс в певних ситуаціях. Наприклад:
int r = 50, k = 4;
if (k != 0 && r / k > 10)
System.out.println("r поділено на k"); // якщо k не нуль, то буде здійснене ділення і порівняно з 10
Оператор присвоєння
ред.Оператор присвоєння доволі вживаний оператор при ініціалізації змінних та присвоєнні результату обчислення виразу.
int x = 5;
int k = x + 8;
Крім того в Java він може застосовуватися для ланцюгового присвоєння змінних
х = k = z = 100;
Дана можливість оператора присвоєння доволі корисна при необхідності присвоєння кільком змінним одного і того ж значення.
Оператор ?:
ред.?: - це тернарний оператор, який має три операнди. Він може заміняти в певних випадках умовну інструкцію виду if-then-else та має наступний вигляд:
Вираз1 ? вираз2 : вираз3;
Розглянемо такий приклад:
int x = 0;
int y = x==0 ? ++x : x;
у данному випадку перевіряється значення х, якщо воно рівне 0, то х збільшується на одиницю і результат присвоюється y, якщо ні, то значення змінної х просто присвоюється змінній y. Варто звернути увагу на те, як спочатку х збільшується на одиницю (++х), а потім присвоюється (детальніше див. про оператор інкременту).
Першочерговість операторів
ред.В операторів програмування як і в математичних операторів є своя першочерговість (пріоритет). Як то операція множення виконується раніше за додавання. І як і в математиці для зміни першочерговості операцій використовуються дужки. Якщо ви невпевнені в якій послідовності будуть виконуватися дії, то використайте їх для прямого вказання порядку виконання операцій у виразі. Крім того використання дужок не впливає на ефективність виконання трансльованої програми і покращує читабельність програми.
Наступна таблиця вказує на першочерговість операцій зверху – донизу.
Першочерговість операторів від найвищого (зверху) до найнижчого (знизу) |
---|
( ) [ ] . |
++ – – ~ ! |
* / % |
+ – |
>> >>> << |
> >= < <= instanceof |
== != |
& |
^ |
| |
&& |
|| |
?: |
= op= |
Додатковий матеріал
ред.