Menu

Оператор switch в Java: case, fall-through и стрелочный синтаксис

Оператор switch в Java с пояснениями: метки case, break и fall-through, ветка default, группировка case, современная стрелочная форма и switch-выражения.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Для чего нужен switch

switch сравнивает одно значение со списком фиксированных вариантов и выполняет ту ветку, которая совпала. Когда вы ловите себя на написании длинной цепочки if/else if, которая снова и снова проверяет одну и ту же переменную на разные константы, switch говорит то же самое яснее.

Он выполняет только проверки на равенство с константами времени компиляции — он не может проверять диапазоны или комбинировать условия. Для этого оставайтесь с if/else.

Классический оператор switch

Традиционная форма использует метки case с двоеточиями и break после каждой ветки:

Java вычисляет day, переходит к совпавшему case, выполняет его инструкции, и break выходит из switch. Ветка default выполняется, когда ничего другое не совпало — считайте её аналогом else. Она необязательна, но включать её — хорошая практика, чтобы неожиданные значения не проскальзывали незаметно.

Ловушка break: fall-through

Это самая распространённая ошибка switch. Если вы пропустите break, выполнение не остановится в конце совпавшего case — оно проваливается в следующий case и продолжает выполняться, пока не встретит break или закрывающую скобку:

Вы могли бы ожидать только Level 1, но этот код печатает все три строки. Поскольку у case 1 нет break, управление соскальзывает прямо в case 2 и case 3. Всегда добавляйте break, если только вам действительно не нужен fall-through — а когда вы на него полагаетесь, оставьте комментарий, чтобы следующий читатель знал, что это сделано намеренно.

Группировка case

У fall-through есть одно законное, аккуратное применение: складывать метки case так, чтобы несколько значений делили один блок. Расположите метки одну за другой без кода между ними:

Здесь 'A', 'B' и 'C' все выполняют одну и ту же строку "Pass". Это задуманный способ сказать «любое из этих значений делает одно и то же».

switch по строкам

Вы не ограничены числами. Начиная с Java 7 вы можете делать switch по String, что идеально подходит для пунктов меню или имён команд:

Сравнение чувствительно к регистру — "Stop" не совпадёт с "stop", поэтому сначала нормализуйте (например, command.toLowerCase()), если регистр ввода может различаться. Ещё одна ловушка: если command равен null, switch выбросит NullPointerException, поэтому защититесь от null, прежде чем дойдёте до него.

Современный стрелочный синтаксис

Более новые версии Java (14+) добавляют стрелочную форму case label -> ..., которая по своей конструкции устраняет ловушку fall-through. Каждый стрелочный case выполняет ровно одну ветку и никогда не проваливается, поэтому нет break, который можно забыть:

Обратите внимание, что значения группируются запятой (case 6, 7) вместо складывания меток, и нет ни единого break. Для нескольких инструкций используйте блок: case 1 -> { ...; ... }. Предпочитайте эту форму в новом коде — она короче и устраняет целый класс ошибок.

switch как выражение

Стрелочная форма также может выдавать значение. switch-выражение возвращает результат, который можно сразу присвоить переменной — без временной переменной, без повторяющегося присваивания в каждой ветке:

Весь switch (...) { ... } вычисляется в число, сохранённое в days. Обратите внимание на точку с запятой после закрывающей скобки — она часть инструкции присваивания. switch-выражение должно быть исчерпывающим (покрывать каждое возможное значение), вот почему здесь стоит default. Если ветке нужно несколько инструкций перед возвратом значения, используйте блок с yield:

case 2 -> {
    boolean leap = (year % 4 == 0);
    yield leap ? 29 : 28;
}

yield — это способ, которым стрелочный блок возвращает своё значение, эквивалент в мире выражений break, несущего результат.

Далее: циклы for

switch выбирает одну ветку из многих; иногда же вам нужно повторить блок много раз. Цикл for выполняет код контролируемое число раз — отсчитывая по диапазону или проходя по каждому элементу — и это следующая страница.

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

Когда стоит использовать switch вместо if-else в Java?

Используйте switch, когда сравниваете одно значение со множеством фиксированных, постоянных вариантов — например, с номером дня, пунктом меню или enum. Он читается яснее, чем длинная цепочка if/else if, и сообщает: «выбери одну ветку из этих известных значений». Оставайтесь с if/else, когда условия включают диапазоны (x > 10), несколько переменных или что-либо, что не является простой проверкой на равенство с константой.

Зачем нужен break в операторе switch в Java?

В классическом синтаксисе с двоеточием, как только case совпадает, выполнение проваливается в последующие case, пока не встретит break или конец switch. break это останавливает. Забыть его — классическая ошибка: вы совпадаете с case 1: и случайно выполняете также код case 2:, case 3: и так далее. Более новый стрелочный синтаксис (case 1 -> ...) никогда не проваливается, поэтому break вы вообще не пишете.

Может ли оператор switch в Java работать со строками (String)?

Да. Начиная с Java 7 вы можете делать switch по String, а также по int, char, byte, short, их типам-обёрткам и значениям enum. Нельзя делать switch по long, double, float или boolean. Сравнение строк чувствительно к регистру, поэтому "Yes" и "yes" — это разные case.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ