Определите вывод программы и объясните роль расположения default в этом switch.
public class Main {
public static void main(String[] args) {
int code = 5;
switch (code) {
case 1:
System.out.print("A");
default:
System.out.print("D");
case 3:
System.out.print("C");
}
}
}
Программа выведет DC. Для значения 5 ни один case не совпадает, поэтому выполнение начинается с default, а затем без break продолжается в следующем case.
Конструкция switch предназначена для выбора одной из нескольких ветвей по значению выражения. В классическом варианте Java она использует модель последовательного выполнения с возможностью fall-through — перехода из одного case в следующий без автоматической остановки.
Такой подход унаследован от традиционных операторов многоветвенного выбора в языках семейства C. Он позволяет явно объединять несколько меток или выполнять общую последовательность действий, но требует аккуратного использования break.
Метка default не обязана находиться в конце switch. Если совпадения с обычными case нет, управление передаётся на default независимо от его положения.
После начала выполнения Java не проверяет последующие метки заново: инструкции выполняются сверху вниз, пока не встретится break, return, исключение или конец switch. Поэтому отсутствие break может привести к неожиданному выполнению нескольких ветвей.
Значение code равно 5. Метки case 1 и case 3 с ним не совпадают, поэтому управление передаётся на default и выполняется:
Затем отсутствует break, поэтому выполнение продолжается в следующем блоке, связанном с case 3:
Итоговый вывод — DC.
Важно, что case и default являются метками, а не независимыми блоками с автоматическим выходом. Если бы после default стоял break, результатом было бы только D.
Если совпадение произошло бы с case 3, выполнение началось бы непосредственно с его инструкции и также вывело бы C. Предыдущие ветви при этом не выполнялись бы.
Для предотвращения случайного fall-through обычно используют break или явно документируют намеренный переход. В версиях Java с современным синтаксисом switch также доступны стрелочные ветви, в которых неявный переход в следующий case отсутствует, но приведённый пример использует классический оператор switch.
Предположим, код обрабатывает числовой статус заказа. Для статусов 1 и 2 нужно выполнить одинаковую проверку, после чего перейти к общей обработке. Один вариант — дублировать код в двух ветвях, но это увеличивает риск расхождения логики.
Другой вариант — использовать намеренный fall-through:
Плюс такого решения — отсутствие дублирования. Минус — случайно пропущенный break может изменить бизнес-логику, поэтому при сложных ветвлениях безопаснее использовать стрелочные ветви или отдельный метод для общей операции. Для совместимости со старым синтаксисом и компактного объединения нескольких значений выбранный вариант с двумя метками и одним break остаётся обоснованным.
default последним?Нет. default может находиться в любом месте switch. Если ни один обычный case не совпал, выполнение начинается с default, а затем продолжается по следующим инструкциям до break или конца конструкции. В приведённом примере именно поэтому получается DC, а не только D.
break после default?При code == 5 выполнится default, будет напечатано D, а break завершит switch, поэтому C не появится. При code == 3 управление сразу начнётся с case 3, и программа выведет C; default не выполняется, поскольку Java не возвращается к предыдущим меткам.
case отдельную область видимости локальных переменных?Нет. В классическом switch метки сами по себе не создают отдельных блоков. Поэтому объявления локальных переменных в разных ветвях могут конфликтовать по области видимости или приводить к ошибкам использования до инициализации. Если ветвям нужны одноимённые локальные переменные, их заключают в отдельные фигурные скобки.