Як і умовна конструкція 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.
В одному 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;
// (...)
}
Тепер можна писати 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 тут не потрібен.
Ще одна відмінність між інструкціями switch та виразами switch: у виразах switch ми ПОВИННІ покрити всі випадки.
Або маючи case для всіх можливих значень, або використавши гілку default.
Замість : можна використовувати ->.
Запис -> дає змогу не додавати ключове слово break.
Обидва записи можна використовувати, але в одному switch потрібно триматися лише одного з них.
switch(expression) {
case 1 -> yield "one"
case 2 -> yield "two"
default: yield "other number" // Removing this will result in a compile error
}
Область видимості.
Традиційний 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 можна знайти в цьому блозі