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

Оператор switch-case в Java 14 фото
Author: Tatyana Milkina

В этой статье мы поговорим с Вами об операторе 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, приведет к ошибке компиляции.

Оператор 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 константа должна соответствовать этому типу. Например, следующий пример не откомпилируется:

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 (new Integer(9)) {
    case 9:
        System.out.println("9");
}

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

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. Например, изменим предыдущий пример, чтобы выводилось только одно слово:

Vegetable p = Vegetable.potato;
switch (p) {
    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 может размещаться в любом месте, необязательно в конце:

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 = null;
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 с перечислением (с enum):

CoffeeSize coffeeSize = CoffeeSize.BIG;
double price = switch (coffeeSize) {
   case BIG:
       yield 2;
   case HUGE:
       yield 3;
   case OVERWHELMING:
       yield 4;
};

Допустим у нас есть какое-то перечисление CoffeeSize, и в этом перечислении есть только три значения BIG, HUGE и OVERWHELMING. Если все значения перечисления указаны в switch, то default блок можем опустить.

2. Switch в Java 14

И теперь давайте перейдём к тем изменениям, которые были внесены в Java 14. Если раньше switch назывался блоковым оператором, то теперь это называется выражение switch. Выражения 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 + ".");
   }
}

В Java 14 было добавлено зарезервированное слово yield, которое упрощает логику возврата результата: 

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, которое возвращает какое-то значение.

В чем отличие зарезервированного слова от ключевого слова. Отличие в том, что ключевые слова мы не можем использовать в качестве идентификаторов. Но зарезервированные слова можно использовать в качестве идентификаторов вне контекста. За пределами блока 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 нельзя, возникнет ошибка компиляции.

Презентацию с видео можно скачать на Patreon.

Курс 'Java для начинающих' на Udemy Курс 'Java для начинающих' на Udemy
Читайте также:
Комментарии