Тернарный оператор Java
Пишите компактные условные выражения в Java с помощью тернарного оператора (condition ? a : b).
Тернарный оператор ?: — единственный оператор Java, принимающий три операнда. Это компактная замена if/else для выражений, а не операторов — то есть он вычисляет значение, которое можно присвоить, вернуть или передать как аргумент. Эта страница описывает синтаксис, случаи, когда он читается естественно, правила совместимости типов двух ветвей и когда лучше использовать if/else или switch.
Синтаксис
condition ? valueIfTrue : valueIfFalseЕсли condition равно true, всё выражение вычисляется как valueIfTrue. В противном случае — как valueIfFalse. Java вычисляет одно — и только одно — из двух значений.
int age = 20;
String status = (age >= 18) ? "adult" : "minor";
System.out.println(status); // adultСкобки вокруг условия необязательны; многие стайл-гайды рекомендуют их для ясности.
Где он особенно удобен
Тернарный оператор лучше всего подходит для одиночных присваиваний или как часть более крупного выражения, где if/else вынудил бы вас разрывать строку:
int max = (a > b) ? a : b;
String label = items.isEmpty() ? "no items" : items.size() + " items";
System.out.println("Hello, " + (name != null ? name : "stranger") + "!");Последняя форма особенно удобна: она позволяет выбрать значение inline без введения временной переменной.
Типы должны быть совместимы
Обе ветви тернарного оператора должны производить совместимые типы. Компилятор выбирает наиболее общий общий тип для всего выражения:
int x = 5;
double d = (x > 0) ? x : 0.0; // result type is doubleПолностью несовместимые ветви — когда ни одно значение не может быть приведено к другому и целевой тип не может принять оба — вызывают ошибку компиляции:
// won't compile: String cannot be converted to int
int n = condition ? 1 : "two";Два несвязанных ссылочных типа, напротив, допустимы, если целевой тип достаточно общий, чтобы принять любой результат. Здесь обе ветви расширяются до их общего супертипа Object:
Object value = condition ? "yes" : 42; // 42 is autoboxed to Integer; type is ObjectЕсли вам нужен конкретный тип, приведите одну ветвь так, чтобы выведенный тип совпадал с ожидаемым.
Не злоупотребляйте вложенностью
Тернарные операторы можно вкладывать — но уже после одного уровня вложенности код становится трудно читать:
String grade = (score >= 90) ? "A"
: (score >= 80) ? "B"
: (score >= 70) ? "C"
: "F";Это пограничный случай; многие команды запрещают даже это. Для более двух ветвей цепочка if/else if или switch почти всегда читается лучше. Используйте тернарный оператор, когда исходов ровно два.
Тернарный оператор vs if/else
Оба компилируются фактически в одинаковый байткод, так что это не вопрос производительности — это вопрос читаемости. Практические правила:
- Используйте тернарный оператор, когда нужно значение — для присваивания, возврата или интерполяции.
- Используйте
if/else, когда нужны операторы — побочные эффекты, несколько строк, логирование.
// good ternary use:
return (errors == 0) ? "OK" : "FAIL";
// bad ternary use — side effects in branches:
boolean ok = (x > 0) ? logSuccess() : logFailure();Второй пример работает, но скрытие побочных эффектов внутри условного выражения затрудняет понимание потока управления. Запишите это явно с if/else.
Безопасные значения по умолчанию при null
Распространённый паттерн: возвращение значения по умолчанию, когда что-то равно null:
String displayName = (user.name != null) ? user.name : "Anonymous";Если вы часто пишете такое, в JDK есть вспомогательный метод — Objects.requireNonNullElse:
import java.util.Objects;
String displayName = Objects.requireNonNullElse(user.name, "Anonymous");Практический пример
Что дальше
Для выбора среди многих вариантов по одному значению оператор switch читается лучше, чем длинная цепочка тернарных операторов. Для операторного ветвления с побочными эффектами используйте if/else, а полный набор операторов сравнения и логических операторов смотрите в разделе операторы Java.