Условия и циклы ·
‹ Предыдущий Следующий ›
⏱ 5 минут чтения Обновлено: 2026-07-12

Оператор switch-case в Java

В этой статье мы поговорим с Вами об операторе switch в Java. Оператор switch в Java — это условный оператор, который дает возможность сравнивать переменную со списком значений.

В Java 14 были внесены значительные изменения в его синтаксис. Мы с Вами рассмотрим, как выглядел блок switch до Java 14, а также какие изменения были внесены в четырнадцатой версии.

1. Классический switch (до Java 14)

Давайте рассмотрим switch на примере — задается число от 1 до 3. Если 1 — включается зеленый цвет светофора, 2 — желтый и 3 — красный. Если любое другое число, то выполнится блок кода default:

public class TrafficLight {
    public static void main(String[] args) {
        int x = 3;
        switch (x) {
            case 1:
                System.out.println("Зеленый");
                break;
            case 2:
                System.out.println("Желтый");
                break;
            case 3:
                System.out.println("Красный");
                break;
            default:
                System.out.println("Неправильно введено число");
                break;
        }
    }
}

Общая форма написания оператора switch:

switch(выражение) {
    case значение1:
        // Блок кода 1
        break;
    case значение2:
        // Блок кода 2
        break;
    ...
    case значениеN:
        // Блок кода N
        break;
    default:
        // Блок кода для default
}

В круглых скобках мы указываем выражение, значение которого будет сравниваться со списком значений, перечисленных после ключевого слова case. Если выражение совпадает со значением1, то выполняется блок кода, указанный после значение1.

Выражение в switch должно иметь тип char, byte, short, intenum (начиная с Java 6) или String (начиная с Java 7). Использование любого другого типа, например, float, long или boolean, приведет к ошибке компиляции.

Оператор switch может только проверять на равенство. Такие операторы, как >= и <=, недопустимы.

Для нескольких значений case можно указывать один блок, как показано в следующем примере:

public class SwitchExample1 {
    public static void main(String[] args) {
        int month = 4;
        String season;
        switch (month) {
            case 12:
            case 1:
            case 2:
                season = "Winter";
                break;
            case 3:
            case 4:
            case 5:
                season = "Spring";
                break;
            case 6:
            case 7:
            case 8:
                season = "Summer";
                break;
            case 9:
            case 10:
            case 11:
                season = "Autumn";
                break;
            default:
                season = "Not a Month";
        }
        System.out.println("April is in the " + season + ".");
    }
}

Если выражение в switch имеет тип, меньший чем int (byte, short или char), case константа должна соответствовать этому типу. Например, следующий пример не откомпилируется, потому что значение 129 выходит за границы типа byte:

byte number = 2;
switch (number) {
    case 13:
    case 129: //compiler error
}

Также нельзя использовать несколько case констант с одним и тем же значением. Следующий блок кода не откомпилируется:

int number = 90;
switch (number) {
    case 50:
        System.out.println("50");
    case 50:
        System.out.println("50"); //compile error
    case 140:
        System.out.println("140");
    default:
        System.out.println("default");
}

Выражение в switch может содержать Character, Byte, Short и Integer значения:

switch (Integer.valueOf(9)) {
    case 9:
        System.out.println("9");
}

Case константы просматриваются сверху вниз, и первая совпавшая case константа в switch является точкой входа. Соответствующий ей блок и все последующие блоки будут выполняться — это называется проваливанием (fall-through). Например:

public class SwitchExample2 {
    public static void main(String[] args) {
        String str = "potato";
        switch (str) {
            case "tomato":
                System.out.print("tomato ");
            case "potato":
                System.out.print("potato ");
            case "cucumber":
                System.out.print("cucumber ");
            default:
                System.out.println("any");
        }
    }
}

Результат выполнения программы:

potato cucumber any

Для того чтобы выйти из switch, используйте ключевое слово break. Например, изменим предыдущий пример, чтобы выводилось только одно слово:

String str = "potato";
switch (str) {
    case "tomato":
        System.out.print("tomato ");
        break;
    case "potato":
        System.out.print("potato ");
        break;
    case "cucumber":
        System.out.print("cucumber ");
        break;
    default:
        System.out.println("any");
}

Результат будет:

potato 

Секция default в switch обрабатывает все значения, которые не указаны явно в одной из case секций. Секция default может размещаться в любом месте, необязательно в конце. Если совпадений с case константами нет, точкой входа становится default, и проваливание продолжается в следующие за ним секции:

public class SwitchExample3 {
    public static void main(String[] args) {
        int z = 8;
        switch (z) {
            case 1:
                System.out.println("Fall to one");
            default:
                System.out.println("default");
            case 3:
                System.out.println("Fall to three");
            case 4:
                System.out.println("Fall to four");
        }
    }
}

Начиная с Java 7 можно использовать объекты типа String в switch. Например:

String exam = "OCPJP 8";
switch (exam) {
    case "OCPJP 7":
        System.out.print(exam + ": 1Z0-804");
        break;
    case "OCPJP 8":
        System.out.print(exam + ": 1Z0-809");
        break;
    default:
        System.out.print(exam + ": ----");
        break;
}

Важно

Если переменная в switch равна null (например, String exam = null;), во время выполнения будет выброшено NullPointerException. Ошибки компиляции при этом нет, поэтому на таком примере часто ошибаются на собеседованиях. Перед switch проверяйте строку на null.

В следующем примере показано использование классического switch с перечислением (с enum). Обратите внимание: в метках case имя константы указывается без имени перечисления — BIG, а не CoffeeSize.BIG:

enum CoffeeSize { BIG, HUGE, OVERWHELMING }

public class CoffeeMachine {
    public static void main(String[] args) {
        CoffeeSize coffeeSize = CoffeeSize.BIG;
        switch (coffeeSize) {
            case BIG:
                System.out.println("Цена: 2");
                break;
            case HUGE:
                System.out.println("Цена: 3");
                break;
            case OVERWHELMING:
                System.out.println("Цена: 4");
                break;
        }
    }
}

2. Выражения switch в Java 14

И теперь давайте перейдем к тем изменениям, которые были внесены в Java 14. Если раньше switch был только оператором, то теперь появилось выражение switch (switch expression). Выражения switch впервые появились даже не в четырнадцатой, а в двенадцатой Java, но это была предварительная версия (preview). В Java 13 они были усовершенствованы, и в Java 14 они уже стали частью основной версии языка.

Выражения switch значительно упрощают код и делают его более читаемым благодаря стрелочному синтаксису (arrow case).

Давайте посмотрим на пример switch в Java 14:

public static void main(String[] args) {
   int x = 2;
   switch (x) {
       case 1 -> System.out.println("Зеленый");
       case 2 -> System.out.println("Желтый");
       case 3 -> {
           System.out.println("Красный");
           System.out.println("Движение запрещено");
       }
       default -> System.out.println("Неправильно введено число");
   }
}

Результат работы программы:

Желтый

Посмотрите, что здесь изменилось по сравнению с предыдущей версией. Теперь вместо двоеточия используется стрелочка — arrow case. И после стрелочки может быть либо одна строка, либо какой-то блок кода. Если это блок кода, то используются фигурные скобочки.

Также одно из изменений четырнадцатой версии Java — при стрелочном синтаксисе всегда выполняется только один блок. То есть проваливание в последующий блок кода, как это было со старой версией switch, не происходит. И поэтому уже нет необходимости писать break для каждого блока кода, как это было в старой версии.

Очень часто switch должен не только выполнить какой-то блок кода, но еще и вернуть значение:

public class SwitchExample2 {
   public static void main(String[] args) {
       int month = 4;
       String season = switch (month) {
           case 12, 1, 2 -> "Winter";
           case 3, 4, 5 -> "Spring";
           case 6, 7, 8 -> "Summer";
           case 9, 10, 11 -> "Autumn";
           default -> "Not a Month";
       };
       System.out.println("April is in the " + season + ".");
   }
}

Обратите внимание еще на одно новшество: несколько значений в одной метке case теперь можно перечислять через запятую — case 12, 1, 2.

В Java 14 было добавлено зарезервированное слово yield, которое возвращает значение из выражения switch, записанного со старым синтаксисом с двоеточием:

public class SwitchExample1 {
   public static void main(String[] args) {
       int month = 4;
       String season = switch (month) {
           case 12, 1, 2:
               yield "Winter";
           case 3, 4, 5:
               yield "Spring";
           case 6, 7, 8:
               yield "Summer";
           case 9, 10, 11:
               yield "Autumn";
           default:
               yield "Not a Month";
       };
       System.out.println("April is in the " + season + ".");
   }
}

Слово yield также используется, когда в стрелочном синтаксисе нужно вернуть значение из блока кода в фигурных скобках:

CoffeeSize coffeeSize = CoffeeSize.BIG;
double price = switch (coffeeSize) {
    case BIG -> 2;
    case HUGE -> 3;
    case OVERWHELMING -> {
        System.out.println("Самый большой размер!");
        yield 4;
    }
};

Выражение switch обязано вернуть значение для любого возможного входного значения. Если тип выражения — enum и все константы перечисления указаны в case, то блок default можно опустить, как в примере выше. Для типов int или String блок default обязателен, иначе возникнет ошибка компиляции.

В чем отличие зарезервированного слова от ключевого слова? Отличие в том, что ключевые слова мы не можем использовать в качестве идентификаторов. Но зарезервированные слова можно использовать в качестве идентификаторов вне контекста. За пределами блока switch мы можем создать переменную с именем yield, и здесь не будет ошибки компиляции:

public static void main(String[] args) {
    int month = 4;
    String season = switch (month) {
        case 12, 1, 2:
            yield "Winter";
        default:
            yield "Not a Month";
    };
    int yield = 6;
}

Но создать переменную с ключевым словом, допустим с ключевым словом case, даже за пределами блока switch нельзя — возникнет ошибка компиляции.

На заметку

Развитие switch не остановилось на Java 14. В Java 21 switch научился сопоставлению с образцом (pattern matching): в метках case можно указывать типы (case Integer i ->) и отдельную метку case null, которая позволяет обработать null без NullPointerException.

Пример сопоставления с образцом в switch (Java 21):

public class PatternMatchingExample {
    public static void main(String[] args) {
        Object obj = 42;
        String result = switch (obj) {
            case null -> "Значение null";
            case Integer i when i > 0 -> "Положительное число: " + i;
            case Integer i -> "Целое число: " + i;
            case String s -> "Строка длиной " + s.length();
            default -> "Другой тип: " + obj.getClass().getSimpleName();
        };
        System.out.println(result);
    }
}

Результат выполнения программы:

Положительное число: 42

Обратите внимание на метку case Integer i when i > 0 — это guarded pattern (метка с условием, ключевое слово when): она сработает только если объект имеет тип Integer и дополнительно проходит проверку в when. Если условие не выполняется, поиск продолжается по следующим меткам — в данном случае сработает более общая case Integer i.

3. Сравнение классического switch и выражений switch

Характеристика Классический switch Выражение switch (Java 14)
Синтаксис метки case 1: case 1 -> (или case 1: с yield)
Несколько значений в метке case 1: case 2: (отдельные метки) case 1, 2 (через запятую)
Проваливание (fall-through) Есть, если не указать break Нет при стрелочном синтаксисе
Возврат значения Нет, только выполнение кода Да, через стрелку или yield
Блок default Необязателен Обязателен, кроме enum со всеми константами в case

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

Что произойдет, если передать в switch строку со значением null?

Во время выполнения будет выброшено NullPointerException — и в классическом switch, и в выражении switch. Компилятор такую ошибку не обнаруживает. Перед switch проверяйте переменную на null, а начиная с Java 21 можно использовать отдельную метку case null.

Какие типы нельзя использовать в выражении switch?

Нельзя использовать long, float, double и boolean. Разрешены char, byte, short, int, их классы-обертки, enum (начиная с Java 6) и String (начиная с Java 7). С Java 21 благодаря pattern matching в switch можно использовать и любой ссылочный тип.

Чем yield отличается от break в switch?

break просто завершает выполнение оператора switch и не возвращает значение. yield завершает выражение switch и возвращает из него результат. При этом yield — зарезервированное, а не ключевое слово: переменную с именем yield создать можно, а с именем break — нет.

Обязателен ли блок default в выражении switch?

Выражение switch должно покрывать все возможные значения. Если тип выражения enum и все его константы перечислены в case, блок default можно опустить. Для int, String и других типов default обязателен, иначе код не откомпилируется. В классическом операторе switch блок default всегда необязателен.

Презентация и видео на Patreon →

Видео объяснение

Предпочитаете видеоформат? Посмотрите этот урок с примерами и объяснениями.

Комментарии

Зарегистрируйтесь или войдите, чтобы иметь возможность оставить комментарий.