1. Булеві операції
Оператори | і & можна застосовувати не тільки до чисел, а й до виразів зі значенням типу boolean.
Однак, як ви вже знаєте, для логічних виразів є оператори && і ||. Що ж нам дасть використання | замість || і використання & замість &&? Чи є взагалі в цьому сенс? Виявляється, є. Іноді.
Логічні оператори || і && виконуються зліва направо за принципом так званих лінивих обчислень.
(вираз1) || (вираз2) || (вираз3)
Якщо вираз1 дорівнює true, немає сенсу обчислювати вираз2 й вираз3: результат все одно буде true.
Тому під час обчислення виразів (а вони обчислюються один за одним зліва направо), щойно ми отримали true, обчислення решти виразів не виконується. І якщо вирази вираз2 й вираз3 містили виклики якихось функцій, то ці функції не викликаються!
Те саме відбувається й у випадку з логічним оператором &&:
(вираз1) && (вираз2) && (вираз3)
Якщо вираз1 дорівнює false, немає сенсу обчислювати вираз2 й вираз3: результат все одно буде false.
Це важливий момент, який дозволяє писати ось такі речі:
String s = null;
if (s != null && s.length() > 0) {
У прикладі вище ми ніколи не отримаємо NullPointerException, оскільки вираз s.length() виконуватиметься, тільки якщо перша частина, s != null, дорівнює true.
Якщо s виявиться рівним null, ліворуч від оператора && буде значення false, і результат усього логічного виразу буде false, тому обчислення другої частини (s.length() > 0) не виконується.
якщо в логічному виразі використати оператор | або оператор &, то лінивого обчислення не вийде — у всіх випадках буде обчислено всі вирази.
2. Пріоритет операцій у Java
Як ви, певно, пам'ятаєте зі шкільного курсу математики, операція множення має вищий пріоритет, ніж операція додавання. А дужки мають іще вищий пріоритет: спочатку обчислюються вирази в дужках, а потім уже виконуються множення/ділення й додавання/віднімання.
Оператори в Java теж мають пріоритет, тільки: а) їх дещо більше, б) деякі оператори виконуються зліва направо, а інші — справа наліво.
Отакий вигляд має таблиця з усіма операторами Java:
| Категорія | Оператор | Асоціативність |
|---|---|---|
| Постфікс | () [] . |
Зліва направо |
| Унарний | ++ -- ! ~ |
Справа наліво |
| Мультиплікативний | * / % |
Зліва направо |
| Адитивний | + - |
Зліва направо |
| Зсув | >> >>> << |
Зліва направо |
| Реляційний | > >= < <= |
Зліва направо |
| Рівність | == != |
Зліва направо |
Побітове І (AND) |
& |
Зліва направо |
Виключне АБО (XOR) |
^ |
Зліва направо |
Побітове АБО (OR) |
| |
Зліва направо |
Логічне І (AND) |
&& |
Зліва направо |
Логічне АБО (OR) |
|| |
Зліва направо |
| Умовний | ?: |
Справа наліво |
| Присвоювання | = += -= *= /= %= >>= <<= &= ^= |= |
Справа наліво |
| Кома | , |
Зліва направо |
У верхньому рядку розташовані найпріоритетніші оператори. Круглі дужки () використовуються для явного встановлення пріоритету. Квадратні дужки [] використовуються для індексування змінної-масиву. Оператор . використовується для отримання полів і методів від посилання на об'єкт або клас.
Що нижче оператори розташовані в таблиці, то нижче їхній пріоритет.
Якщо ви використовуєте у виразі кілька операторів, не лінуйтеся — ставте дужки.
Так, у Java можна написати щось на кшталт if (a & 1<<b > ~c), але так робити не варто. Ви пишете код не лише для компілятора, але й для інших програмістів. Що читабельнішим буде код, то краще.
3. Префіксний і постфіксний інкременти
Як ви вже знаєте, у Java є оператор інкременту (++) і оператор декременту (--), які збільшують і зменшують значення змінної на 1.
Однак ви, напевно, не знаєте, що є два види цих операцій: префіксні (оператор ставиться перед змінною) і постфіксні (оператор ставиться після змінної). І працюють ці оператори трохи по-різному.
У Java можна написати такий вираз:
int a = 5;
int b = a++;
Якщо оператор ++ стоїть після змінної та водночас ця змінна входить в якийсь вираз (як у прикладі вище), то у виразі буде використано поточне значення змінної, а тільки потім його буде збільшено на 1.
Інакше кажучи, відбудеться приблизно от що:
int a = 5;
int b = a;
a = a + 1;
Тобто b матиме значення 5, а не 6, як це могло здатися спочатку.
Якщо ж оператор ++ стоїть перед змінною і змінна входить в якийсь вираз, її значення спочатку буде збільшено на 1, а тільки потім використано у виразі.
int a = 5;
int b = ++a;
Приклад вище еквівалентний такому прикладу:
int a = 5;
a = a + 1;
int b = a;
Отут вже значення b дорівнюватиме 6.
Є навіть один приклад, який використовують Java-програмісти, щоб визначити, чи їхній співрозмовник — теж Java-програміст:
int a = 5;
int b = ++a + ++a;
Так, це теж правильний запис.
Цей приклад відмінно скомпілюється й перетвориться приблизно на таке:
int a = 5;
a = a + 1;
int v1 = a;
a = a + 1;
int v2 = a;
int b = v1 + v2;
Для оператора -- все відбувається аналогічно.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ