Для чего нужен 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.