Треки
/
Java
Java
/
Салабус
/
Конструкція `switch`
Ко

Конструкція `switch` у Java

2 вправи

Про концепцію Конструкція `switch`

Як і умовна конструкція if/else, інструкція switch дає змогу змінювати плин програми, виконуючи код за певної умови. Різниця в тому, що інструкція switch може порівнювати значення виразу примітивного типу або рядка тексту (англ. string) лише із наперед визначеними сталими.

Під час роботи з інструкцією switch стануть у пригоді деякі ключові слова.

  • switch: це ключове слово дає змогу оголосити структуру switch. Після нього записують вираз або змінну, від якої залежатиме результат.
  • case: ним ми оголошуємо різні можливі варіанти результату.
  • break: ключове слово break дуже корисне, щоб зупинити виконання switch у кінці потрібної гілки. Якщо його забути, програма продовжить роботу, і результат може бути несподіваним.
  • default: як видно з назви, його використовують як типовий результат, коли жоден інший case не збігається з результатом виразу.

У найпростішому випадку вона перевіряє вираз примітивного типу або рядок тексту й ухвалює рішення на основі його значення. Наприклад:

String direction = getDirection();
switch (direction) {
    case "left":
        goLeft();
        break;
    case "right":
        goRight();
        break;
    default:
        // otherwise
        markTime();
        break;
}

Починаючи з Java 14 (а як попередній перегляд вона була доступна вже в Java 12 і 13), можна використовувати «розширену» реалізацію switch.

  1. В одному case можна вказати кілька значень. У традиційній інструкції switch можна скористатися провалюванням. У наведеному нижче прикладі case 1 і case 3 виконають той самий код. Це відбувається тому, що case 1 не використовує ключове слово break.

    switch (number) {
        case 1:
        case 3:
            // do same stuff
            break;
        case 2:
            // do different stuff
            break;
        // (...)
    }
    

    У розширеному switch expression можна одразу вказати кілька значень для case. Розгляньмо такий приклад:

    switch (number) {
        case 1, 3:
            // do stuff
            break;
        case 2:
            // do other stuff
            break;
        // (...)
    }
    
  2. Тепер можна писати switch-statement або switch expression. У чому різниця? Загалом інструкція вимагає строгої логіки, тоді як вираз може повертати значення. Замість такого коду:

    String result = "";
    switch (expression) {
        case "bob":
            result = "bob";
            break;
        // (...)
    }
    

    Можна зробити так:

    String result = switch (expression) {
        case "bob":
            yield "bob";
        // (...)
    }
    

    yield працює так само, як return, але для виразу switch. Оскільки yield завершує вираз, break тут не потрібен.

  3. Ще одна відмінність між інструкціями switch та виразами switch: у виразах switch ми ПОВИННІ покрити всі випадки. Або маючи case для всіх можливих значень, або використавши гілку default.

  4. Замість : можна використовувати ->. Запис -> дає змогу не додавати ключове слово break. Обидва записи можна використовувати, але в одному switch потрібно триматися лише одного з них.

     switch(expression) {
         case 1 -> yield "one"
         case 2 -> yield "two"
         default: yield "other number" // Removing this will result in a compile error
     }
    
  5. Область видимості. Традиційний switch може призводити до несподіваної поведінки через свою область видимості, адже для всього switch вона спільна.

     switch(expression) {
         case 1:
             String message = "something";
             break;
         case 2:
             String message = "anything";
             break;
         // (...)
     }
    

    Цей приклад не працює, бо змінна message оголошена в switch двічі. Це можна виправити так:

     switch (expression) {
         case 1: {
             String message = "something";
             break;
         }
         case 2: {
             String message = "anything";
             break;
         }
         // (...)
     }
    

    Тут {} обмежують область видимості case. Проте це не інтуїтивно, бо {} не обовʼязкові. А якщо ми використовуємо новий запис ->, то після нього має бути щось одне: одна інструкція або вираз, інструкція throw або блок {}. Жодної плутанини!

Більше інформації про розширений switch можна знайти в цій статті та ось цій, а також в офіційній документації Oracle.

Крім того, у Java 21 додали можливість під назвою Guarded Patterns, яка дає змогу виконувати перевірки безпосередньо в мітці case.

String dayOfMonth = getDayOfMonth();
String day = "";
return switch (day) {
    case "Tuesday" when dayOfMonth == 13 -> "Forbidden day!!";
    case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "Week day";
    case "Saturday", "Sunday" -> "Weekend";
    default -> "Unknown";
};

Більше інформації про вираз switch у Java 21 можна знайти в цьому блозі

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Конструкція `switch`