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;
Для оператора --
все відбувається аналогічно.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ