Логические операторы Java
Комбинируйте boolean-выражения с помощью &&, || и ! и изучите вычисление с коротким замыканием в Java.
Логические операторы объединяют значения boolean в более сложные проверки. Java предоставляет три: AND (&&), OR (||) и NOT (!). Ключевая особенность && и || — короткое замыкание — делает их безопасными для использования даже тогда, когда один из операндов может вызвать исключение.
Обычно boolean-операнды формируются с помощью операторов сравнения (например, >= или !=), а затем связываются между собой логическими операторами, описанными на этой странице. Здесь рассматривается каждый оператор, вычисление с коротким замыканием, приоритет операторов, распространённые практические шаблоны и законы Де Моргана.
Три оператора
| Оператор | Название | Результат |
|---|---|---|
&& | AND | true только если оба операнда равны true |
|| | OR | true если хотя бы один операнд равен true |
! | NOT | инвертирует boolean — !true равно false |
Их полное поведение умещается в небольшой таблице истинности:
a | b | a && b | a || b | !a |
|---|---|---|---|---|
true | true | true | true | false |
true | false | false | true | false |
false | true | false | true | true |
false | false | false | false | true |
boolean isAdult = age >= 18;
boolean hasTicket = ticket != null;
if (isAdult && hasTicket) {
enterCinema();
}
if (isHoliday || isWeekend) {
sleepIn();
}
if (!isLoggedIn) {
redirectToLogin();
}boolean, но не с числами. В Java нет понятий «истинный» или «ложный» — if (count) является ошибкой компиляции; пишите if (count > 0). Не путайте логические &&/|| с оператором сравнения ==: сравнение возвращает boolean, а логические операторы объединяют несколько таких значений.Вычисление с коротким замыканием
&& вычисляет правую часть только если левая часть равна true. Если левая часть равна false, результат уже известен и правая часть пропускается:
boolean leftFalse = false && expensiveCall(); // expensiveCall() never runs|| работает аналогично — правая часть пропускается, если левая равна true:
boolean leftTrue = true || expensiveCall(); // expensiveCall() never runsЭто крайне важно при проверке на null:
if (user != null && user.isActive()) { ... }Если user равен null, правая часть пропускается — никакого NullPointerException. Перестановка операндов привела бы к сбою:
if (user.isActive() && user != null) { ... } // NPE when user is nullПрактическое правило: сначала ставьте самую дешёвую, безопасную или наиболее вероятно провальную проверку.
Операторы без короткого замыкания: & и |
В Java также есть & и | (одиночные символы). Применительно к boolean они вычисляют то же AND/OR, но всегда вычисляют обе стороны. Использовать их для boolean почти никогда не нужно — они существуют в основном для побитовых операций над целыми числами (рассмотрены в Java Bitwise Operators).
boolean a = false & expensiveCall(); // expensiveCall() DOES run
boolean b = true | expensiveCall(); // expensiveCall() DOES runЕсли вам кажется, что нужно использовать & или | с boolean-значениями, скорее всего вам нужны && и ||.
Комбинирование операторов
Логические операторы можно объединять в цепочки для построения любых булевых проверок:
boolean validAge = age >= 13 && age < 120;
boolean validUser = (name != null && !name.isBlank()) && validAge;
if (isWeekend || (isHoliday && !isWorkRequired)) {
relax();
}! имеет наибольший приоритет, затем &&, затем ||. При их смешивании добавляйте скобки для ясности, даже если они строго не обязательны.
Распространённые шаблоны
Проверка диапазона — объедините два реляционных теста с &&:
if (x >= 0 && x < array.length) { ... }Белый список — объедините несколько проверок на равенство с ||:
if (status.equals("READY") || status.equals("RUNNING") || status.equals("DONE")) { ... }(Для длинных списков предпочтительнее List.of(...).contains(status) или конструкция switch.)
Защитные условия — быстрый выход с !:
if (!isAuthenticated) {
throw new AuthException();
}
// ... main logic ...Законы Де Моргана
При отрицании составного выражения операторы меняются на противоположные:
!(a && b) is the same as !a || !b
!(a || b) is the same as !a && !bТаким образом, !(age >= 18 && hasId) эквивалентно age < 18 || !hasId. Большинству читателей проще воспринимать положительную форму — по возможности переписывайте код так, чтобы он был понятнее.
Демонстрация
Что дальше
- Java If...Else — где эти булевы проверки реально применяются для ветвления кода.
- Java Bitwise Operators — для редких случаев, когда действительно нужно манипулировать отдельными битами.