Операторы Java ·
‹ Previous Next ›
⏱ 5 min read Modified: 2026-07-11

Тернарный оператор в Java

Тернарный оператор ?: (в спецификации Java он называется условным оператором, conditional operator) — единственный оператор языка с тремя операндами, отсюда и название «тернарный». Он выбирает одно из двух значений в зависимости от условия и часто используется вместо короткого оператора if-else. Главное отличие: тернарный оператор — это выражение, то есть он возвращает значение, которое можно сразу присвоить переменной, передать в метод или вернуть из метода.

Синтаксис тернарного оператора

Общая форма тернарного оператора:

условие ? выражение1 : выражение2

Условие — любое выражение, вычисление которого даёт логическое значение типа boolean (например, сравнение или комбинация логических операторов).

Если условие истинно (true), вычисляется выражение1 и его значение становится результатом всей операции; в противном случае вычисляется выражение2. Важно: вычисляется только одна из двух ветвей — вторая не выполняется вовсе.

Выражение1 и выражение2 должны возвращать значения одинакового или совместимого типа, и этим типом не может быть void.

Важно

Тернарный оператор — это выражение, а не оператор потока управления. Он обязан вернуть значение, поэтому запись вида условие ? doThis() : doThat(); отдельной строкой не скомпилируется, если методы возвращают void. Когда нужно просто выполнить одно из двух действий, используйте if-else.

Пример использования

Классический пример — получение абсолютного значения числа: если i отрицательно, берём -i, иначе само i:

public class TernaryOperationExample1 {
    public static void main(String[] args) {
        int i, k;
        i = -10;
        k = i < 0 ? -i : i; // абсолютное значение переменной i
        System.out.print("Абсолютное значение ");
        System.out.println(i + " равно " + k); // Абсолютное значение -10 равно 10
    }
}

Тот же результат с if-else занял бы четыре строки. Ещё несколько типичных применений — в аргументе метода и в return:

int a = 7, b = 12;
System.out.println(a > b ? "a больше" : "b больше или равно"); // в аргументе метода

int max(int x, int y) {
    return x > y ? x : y; // в операторе return
}

Тернарный оператор или if-else: что выбрать

Тернарный оператор и if-else не взаимозаменяемы полностью — у каждого своя область применения:

Ситуация Что использовать Почему
Выбор одного из двух значений при присваивании или в return Тернарный оператор Короче и читается как единое выражение: k = i < 0 ? -i : i;
Выполнение действий (вывод, изменение состояния), а не выбор значения if-else Тернарный оператор обязан вернуть значение и не может быть отдельной инструкцией с void-ветвями
В ветвях несколько инструкций if-else Каждая ветвь тернарного оператора — ровно одно выражение
Три и более вариантов выбора if-else if или switch-выражение Цепочки вложенных тернарников трудно читать

Вложенные тернарные операторы

Ветвью тернарного оператора может быть другой тернарный оператор. Оператор правоассоциативен: выражение a ? b : c ? d : e вычисляется как a ? b : (c ? d : e), поэтому цепочка без скобок читается сверху вниз, как if-else if:

public class NestedTernaryExample {
    public static void main(String[] args) {
        int score = 74;
        String grade = score >= 90 ? "отлично"
                     : score >= 70 ? "хорошо"
                     : score >= 50 ? "удовлетворительно"
                     : "неудовлетворительно";
        System.out.println(grade); // хорошо
    }
}

Один уровень вложенности с таким «лесенкой»-форматированием ещё допустим, но более глубокие или расставленные в произвольном порядке вложенные тернарники быстро превращаются в головоломку. Начиная с Java 14 для выбора из нескольких вариантов удобнее switch-выражение, которое, как и тернарный оператор, возвращает значение:

String size = switch (code) {
    case 1 -> "S";
    case 2 -> "M";
    default -> "L";
};

Типичные ловушки

Две особенности тернарного оператора регулярно встречаются в вопросах на собеседованиях.

1. Числовое расширение типов (numeric promotion). Если ветви имеют разные числовые типы, результат приводится к общему типу до выбора ветви:

Object result = true ? 1 : 2.0;
System.out.println(result); // 1.0, а не 1!

Хотя условие истинно и выбрана ветвь 1, типом всего выражения является double (общий тип для int и double), поэтому 1 превращается в 1.0.

2. NullPointerException при автораспаковке. Если одна ветвь имеет тип-обёртку (Integer), а другая — примитив (int), типом выражения становится примитив, и обёртка автоматически распаковывается. Если в ней null — программа падает:

Integer count = null;
boolean flag = true;
int r = flag ? count : 0; // NullPointerException: count распаковывается в int

Важно

Тип результата тернарного оператора определяется обоими ветвями на этапе компиляции, а не той ветвью, которая фактически выполнится. Смешивание int и double даёт double; смешивание Integer и int даёт int с автораспаковкой — и риском NullPointerException. Держите обе ветви одного типа.

Стиль и читаемость

Несколько практических рекомендаций:

  • Используйте тернарный оператор для коротких выборов одного из двух значений; как только выражение перестаёт помещаться в одну строку и читаться с первого взгляда — переходите на if-else.
  • Избегайте побочных эффектов в ветвях (вызовов методов, меняющих состояние): читающий код ожидает от тернарного оператора простого выбора значения.
  • Не вкладывайте тернарные операторы глубже одного уровня; для цепочек условий берите if-else if или switch-выражение.
  • При сомнениях в приоритете операторов заключайте условие в скобки: (a > b) ? a : b — это ничего не меняет для компилятора, но помогает читателю.

Часто задаваемые вопросы

Чем тернарный оператор отличается от if-else в Java?

Тернарный оператор — это выражение: он возвращает значение, которое можно присвоить переменной, передать в метод или вернуть через return. Оператор if-else — инструкция потока управления: он выполняет действия, но сам ничего не возвращает. По скорости они эквивалентны — выбор определяется читаемостью, а не производительностью.

Можно ли вкладывать тернарные операторы друг в друга?

Да, ветвью тернарного оператора может быть другой тернарный оператор. Оператор правоассоциативен: a ? b : c ? d : e означает a ? b : (c ? d : e) и читается как цепочка if-else if. Однако глубокая вложенность плохо читается — для трёх и более вариантов лучше использовать if-else if или switch-выражение (Java 14+).

Почему выражение true ? 1 : 2.0 возвращает 1.0, а не 1?

Тип результата тернарного оператора вычисляется компилятором из типов обеих ветвей, а не той, что реально выполнится. Для int и double общим типом является double, поэтому значение 1 расширяется до 1.0. Чтобы избежать сюрпризов, делайте обе ветви одного типа.

Может ли тернарный оператор выбросить NullPointerException?

Да. Если одна ветвь имеет тип-обёртку, например Integer, а другая — примитив int, типом всего выражения становится примитив, и значение обёртки автоматически распаковывается. Если в ней хранится null, распаковка приводит к NullPointerException, даже когда условие выглядит безобидно. Решение — привести обе ветви к одному типу.

Презентацию с видео можно скачать на Patreon.

Video Explanation

Prefer video format? Watch this lesson with examples and explanations.

Comments

Please log in or register to have a possibility to add comment.