ПрограммированиеBackend разработчик

Что такое switch-выражение в Java, как оно отличается от классического switch и какие тонкости есть при его использовании?

Проходите собеседования с ИИ помощником Hintsage

Ответ.

История вопроса:

До Java 12 оператор switch использовался исключительно как statement. С выходом Java 12/14 появились switch-выражения (switch expression), которые расширили синтаксис и возможности оператора. Switch-выражения предназначены для более лаконичного и выразительного кода.

Проблема:

Классический switch часто вызывает ошибки: забытый break ведёт к fall-through, трудочитаемость при множестве кейсов, невозможность вернуть результат напрямую в выражении, отсутствие исчерпывающей проверки значений.

Решение:

Switch-выражение может возвращать значение, использовать стрелочный синтаксис, поддерживать исчерпывающий анализ на этапе компиляции и обрабатывать null через default. Имеет синтаксис:

String result = switch(day) { case MONDAY, FRIDAY -> "Workday"; case SATURDAY, SUNDAY -> "Weekend"; default -> throw new IllegalArgumentException(); };

Ключевые особенности:

  • Switch стал выражением: можно присваивать его результат переменной.
  • Новый синтаксис облегчает чтение и предотвращает забытые break.
  • Поддержка множественных меток (case A, B -> ...).

Вопросы с подвохом.

Может ли switch работать с enum, строками и null?

С enum работает с Java 5. Со строками с Java 7. Null обрабатывается только через default, иначе будет NPE.

switch(day) { // day == null default: System.out.println("null"); } // работает

Что произойдёт, если не реализовать все варианты enum в switch-выражении?

Компилятор потребует default или implementation для всех значений. При отсутствии этого будет ошибка компиляции.

Можно ли использовать break в switch-выражении нового типа?

В стрелочном варианте break не нужен. Если использовать блок (case X -> { ... }), можно применить yield для возврата значения:

int num = switch(x) { case 1 -> 10; case 2 -> { yield 20; } default -> 0; };

Типовые ошибки и анти-паттерны

  • Отсутствие default при работе с не-nullable типами приведёт к ошибке компиляции.
  • Попытка обработки null вне default вызовет NullPointerException.
  • Использование switch с большим количеством вложенности, вместо полиморфизма.

Пример из жизни

Негативный кейс

Классический switch с int без break:

switch(type) { case 1: actionA(); case 2: actionB(); // вызывается и при type==1 и type==2 }

Плюсы:

  • Быстро написать.

Минусы:

  • Недочёты приводят к критическим багам.
  • Код трудно читать и сопровождать.

Позитивный кейс

Использование нового switch-выражения для сопоставления enum с результатом:

String status = switch(orderStatus) { case PAID -> "Оплачен"; case CANCELED -> "Отменён"; default -> "В обработке"; };

Плюсы:

  • Исчерпывающий анализ — ошибок меньше.
  • Код компактный и читаемый.

Минусы:

  • Требует Java 14+ и знаний современного синтаксиса.