Условные конструкции
if / else
if выбирает ветку по выражению типа boolean:
if (temperature < 0) {
state = "ICE";
} else if (temperature == 0) {
state = "BOUNDARY";
} else {
state = "WATER";
}Java не преобразует число или ссылку в boolean. Условия лучше строить из названных предикатов и избегать глубокой вложенности.
Короткое замыкание
&& и || вычисляют правую часть только при необходимости:
if (user != null && user.isActive()) {
allow(user);
}Операторы & и | применимы и к boolean, но вычисляют обе стороны. Они нужны реже; побочные эффекты в условиях затрудняют чтение.
Тернарный оператор
Тернарное выражение возвращает значение:
String label = count == 0 ? "empty" : "items=" + count;Оно удобно для простого выбора. Вложенные тернарные выражения обычно лучше заменить if или отдельным методом. Тип результата определяется обеими ветками и правилами преобразования типов.
switch
Классический switch использует переход к метке и требует break, чтобы не провалиться дальше:
switch (status) {
case NEW:
initialize();
break;
case READY:
execute();
break;
default:
reject();
}Современная форма со стрелками не имеет случайного fall-through и может быть выражением:
int priority = switch (status) {
case NEW -> 10;
case READY -> 1;
case DONE -> 100;
};Для enum исчерпывающий switch без default полезен: при добавлении константы компилятор потребует обновить выражение.
Блок может вернуть значение через yield:
String message = switch (status) {
case NEW -> "created";
case READY -> {
audit(status);
yield "available";
}
case DONE -> "finished";
};switch над null выбрасывает NullPointerException, если современный pattern switch не содержит явный case null. Границу null лучше определить в самом контракте, а не случайно доверять default.
Pattern matching
Проверку типа можно совместить с объявлением переменной:
if (value instanceof String text && !text.isBlank()) {
System.out.println(text.length());
}Переменная text доступна только там, где компилятор доказал успешность проверки.
Ловушки
- Случайный fall-through в классическом
switch. Booleanсо значениемnullв условии: unboxing приведёт кNullPointerException.- Побочные эффекты в правой части
&&/||, выполнение которых зависит от левой. - Сравнение строк через
==в условии. default, который скрывает необходимость обработать новую константу enum.- Слишком сложное условие без выделенных именованных предикатов.
Вопросы на собеседовании
- Чем
&&отличается от&для boolean? - Что такое fall-through в
switch? - Чем switch-выражение отличается от классического switch-оператора?
- Что произойдёт при
if (nullableBoolean)и значенииnull? - Когда отсутствие
defaultв switch по enum полезно? - Как pattern matching для
instanceofвлияет на область видимости переменной?
Связанные заметки
Переменные и типы данных Java · Преобразование типов Java · Работа со строковыми данными · Работа с исключениями в Java