JavaRush /Курсы /JAVA 25 SELF /Продвинутые switch-...

Продвинутые switch-выражения

JAVA 25 SELF
10 уровень , 5 лекция
Открыта

1. Что нового в switch

Если вдруг вы писали на Java до 14-й версии, то switch выглядел примерно так:

switch (day) 
{
    case MONDAY:
        System.out.println("Начало недели!");
        break;
    case FRIDAY:
        System.out.println("Пятница, ура!");
        break;
    default:
        System.out.println("Обычный день.");
        break;
}

Вроде бы ничего страшного, но:

  • Нужно не забыть break (иначе «провалимся» в следующий case).
  • Много повторяющегося кода.
  • Если хочется вернуть значение, приходится объявлять переменную заранее и присваивать ей значение внутри каждого case.

Java 14+ решила: хватит этого! Пора сделать switch более удобным и современным.

Основные нововведения:

  • Switch стал выражением, а не только оператором — теперь он может возвращать значение.
  • Новый синтаксис со стрелкой -> вместо двоеточий и break.
  • Несколько case через запятую — для одинаковой логики.
  • Компилятор проверяет, что все варианты обработаны (особенно с enum).
  • Нет риска «проваливания» (fall-through) — теперь это возможно только явно.

2. Синтаксис switch-выражения


switch (значение)
{
   case A, B -> результат1;
   case C -> {
      // несколько действий
      yield результат2;
   }
   default -> результатПоУмолчанию;
}
Синтаксис switch-выражения с -> и yield

Базовый пример

Давайте сразу к делу. Вот как теперь можно возвращать значение из switch:

DayOfWeek day = DayOfWeek.MONDAY;

String message = switch (day) 
{
    case MONDAY, FRIDAY, SUNDAY -> "Короткая неделя или выходной!";
    case TUESDAY                -> "Вторник — день тяжёлый.";
    case WEDNESDAY, THURSDAY    -> "Середина недели!";
    case SATURDAY               -> "Ура, суббота!";
    // Обязательно должен быть default, если не все варианты обработаны
    default                     -> "Какой-то странный день...";
};

System.out.println(message);

Что здесь происходит:

  • switch (day) — выражение, возвращающее значение.
  • После стрелки -> указывается результат для этого case.
  • Несколько case можно объединить через запятую.
  • Нет ни одного break — Java сама знает, где заканчивается ветка.
  • Можно сразу присваивать результат переменной message.

Пример с числами

int code = 404;
String result = switch (code) 
{
    case 200 -> "OK";
    case 400, 404 -> "Ошибка клиента";
    case 500 -> "Ошибка сервера";
    default -> "Неизвестный код";
};
System.out.println(result);

Пример со строками

String command = "start";
String status = switch (command) 
{
    case "start" -> "Запуск!";
    case "stop" -> "Остановка!";
    case "pause" -> "Пауза...";
    default -> "Неизвестная команда";
};
System.out.println(status);

Использование блока с yield

Иногда хочется выполнить несколько действий для одного case (например, вычислить что-то сложное или сделать логирование). Для этого можно использовать блок { ... } и ключевое слово yield:

int n = 7;
String parity = switch (n % 2) 
{
    case 0 -> "Чётное";
    case 1 -> 
    {
        System.out.println("Обнаружено нечётное число: " + n);
        yield "Нечётное";
    }
    default -> "Что-то странное";
};
System.out.println(parity);

Важно: в блоке обязательно должен быть yield, который возвращает значение для этого case.

3. Преимущества нового синтаксиса

Нет необходимости в break

В классическом switch забытый break — источник боли и загадочных багов. В новом синтаксисе break не нужен вообще: каждая ветка завершается автоматически.

Компилятор проверяет обработку всех вариантов

Если вы используете enum и не обработали все значения — компилятор не даст собрать проект без default. Это делает код надёжнее.

Нет "проваливания" (fall-through)

В классическом switch, если забыть break, выполнение «провалится» в следующий case. В новом синтаксисе это невозможно (разве что вы используете блок с инструкциями и явно пишете break — но здесь он не нужен).

Код компактнее и читаемее

Сравните сами:

До:

String result;
switch (status) {
    case "OK":
        result = "Всё хорошо";
        break;
    case "ERROR":
        result = "Ошибка";
        break;
    default:
        result = "Неизвестно";
        break;
}

После:

String result = switch (status) {
    case "OK" -> "Всё хорошо";
    case "ERROR" -> "Ошибка";
    default -> "Неизвестно";
};

Несколько case — одна логика

case MONDAY, FRIDAY, SUNDAY -> "Выходной или короткий день!";

4. Сравнение с классическим switch

Особенность Классический switch Новый switch
break обязателен Да Нет
Проваливание (fall-through) Да Нет
Может возвращать значение Нет (только через переменную) Да (выражение)
Несколько case через запятую Нет Да
Проверка всех вариантов Нет Да (особенно с enum)
Компактность Много кода Коротко и ясно
Использование с enum и строками Да Да

5. Совместимость с enum и строками

Пример с enum

Допустим, у нас есть перечисление:

enum DayOfWeek 
{
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

Используем его в новом switch:

DayOfWeek today = DayOfWeek.WEDNESDAY;

String mood = switch (today) 
{
    case MONDAY -> "Тяжело вставать...";
    case FRIDAY -> "Скоро выходные!";
    case SATURDAY, SUNDAY -> "Ура, отдых!";
    default -> "Рабочий день.";
};
System.out.println(mood);

Пример со String

String season = "summer";
String activity = switch (season) 
{
    case "winter" -> "Кататься на коньках";
    case "summer" -> "Плавать в озере";
    case "autumn" -> "Собирать грибы";
    case "spring" -> "Слушать пение птиц";
    default -> "Неизвестное время года";
};
System.out.println(activity);

6. Переписываем старый switch на новый стиль

Было:

int day = 3;
String dayName;
switch (day) 
{
    case 1:
        dayName = "Понедельник";
        break;
    case 2:
        dayName = "Вторник";
        break;
    case 3:
        dayName = "Среда";
        break;
    default:
        dayName = "Неизвестный день";
        break;
}
System.out.println(dayName);

Стало:

int day = 3;
String dayName = switch (day) 
{
    case 1 -> "Понедельник";
    case 2 -> "Вторник";
    case 3 -> "Среда";
    default -> "Неизвестный день";
};
System.out.println(dayName);

Ещё пример: несколько case — одна логика

int score = 5;
String grade = switch (score) 
{
    case 5, 6, 7 -> "Хорошо";
    case 8, 9, 10 -> "Отлично";
    default -> "Нужно постараться";
};
System.out.println(grade);

7. Типичные ошибки и особенности

Ошибка №1: отсутствие default, если не все варианты обработаны. Если вы используете switch-выражение с типом, у которого могут быть значения вне перечисленных case (например, с int или String), компилятор потребует default. Для enum, если вы не обработали все значения, default тоже обязателен.

Ошибка №2: забыли yield в блоке. Если используете фигурные скобки для case (нужно выполнить несколько действий), не забудьте про yield — без него компилятор выдаст ошибку: "Missing yield statement".

Ошибка №3: несовпадение типов. Все ветки switch-выражения должны возвращать значения одного типа; иначе компилятор не пропустит код.

Ошибка №4: дублирование значений case. Указывать один и тот же case дважды нельзя — компилятор сразу сообщит об ошибке.

1
Задача
JAVA 25 SELF, 10 уровень, 5 лекция
Недоступна
Обработка ответов сервера 🌐
Обработка ответов сервера 🌐
1
Задача
JAVA 25 SELF, 10 уровень, 5 лекция
Недоступна
Управление дроном 🚁
Управление дроном 🚁
1
Задача
JAVA 25 SELF, 10 уровень, 5 лекция
Недоступна
Обновление старого планировщика 📅
Обновление старого планировщика 📅
1
Задача
JAVA 25 SELF, 10 уровень, 5 лекция
Недоступна
Автоматическое присвоение оценок студентам 🎓
Автоматическое присвоение оценок студентам 🎓
1
Опрос
Константы, enum и switch, 10 уровень, 5 лекция
Недоступен
Константы, enum и switch
Константы, enum и switch
Комментарии (12)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Natig Soltanov Уровень 15
3 марта 2026
Если кто то не понял для чего нужен Yield: Если вам нужно вернуть какое то значение, вы обычно используете return value; но в таком случае метод вернёт значение и остановится полностью. То есть весь код после этого работать не будет. Для этого придумали yield, чтобы возвращать значение case внутри switch при этом не останавливая работу самого метода и не влияя на него. Как бы локальный return
matematik200 Уровень 19
23 января 2026
WEDNESDAY, THURSDAY - кажется неверно написано
Александр Уровень 13
21 января 2026

  int dayNumber = 2;
        
        String dayNameString = switch(dayNumber){
            case 1 -> "Понедельник";
            case 2 -> "Вторник";
            case 3 -> "Среда";
            default -> "Неизвестынй день";
        };
        
        System.out.println(dayNameString);
не понимаю где ошибка, он не пропускает)
Vladislav Barkhanov Уровень 24
19 февраля 2026
default -> "Неизвестынй день"; // Ошибка: "н"
zhur1k Уровень 21
15 ноября 2025
Ну что это? в описании задачи все строки кроме "ОК" значит на кириллице, а "ОК" на латинице. Ну и как мне стоило догадаться?
dansyrkin Уровень 2
30 ноября 2025
Согласен. Сам изначально написал на латинице, потом увидел, что остальное на кириллице и исправил. А потом здравствуйте...
Popka Уровень 24
25 декабря 2025
да пофиг нет? тут нет поощрений за безошибочное решение. Хоть с 100 попытки завершай. Плюс ты же сам прекрасно понимаешь что ты все верно сделал тебе просто буквы заменить
Kidze Уровень 26
1 ноября 2025
Выглядит круто по сравнению со старой версией и главное интуитивно все понятно.
Daniil Tsvichenko Уровень 21
14 декабря 2025
так-то оно да, но грустно, что проваливание не реализовать теперь. отожран кусок логики
17 декабря 2025
Так ведь использовать старый switch-case никто не запрещает
Daniil Tsvichenko Уровень 21
18 декабря 2025
так-то оно да, но было бы здорово миксануть их в одно целое. я не пробовал, но очень сомневаюсь, что оно заработает, если так сделать
Alina Gabidulina Уровень 32
17 октября 2025
Ну наконец-то свитч можно будет писать без брейка, ура дождались!