Switch expressions (Java 14)
В классической форме switch — это оператор (statement): он что-то делает, но ничего не возвращает. С Java 14 (JEP 361) switch стал ещё и выражением (expression) — он может возвращать значение, которое присваивается переменной или возвращается из метода.
Вместе с этим появился короткий стрелочный синтаксис (case L -> ...), который автоматически выполняет break после каждой ветки. Это убирает классическую ошибку «забыл break и провалился в следующий case».
Минимальная версия: Java 14.
Синтаксис
// Стрелочная форма (без fall-through)
var result = switch (value) {
case A, B -> "a or b";
case C -> "c";
default -> "other";
};
// С блоком и yield
var x = switch (value) {
case 1 -> 100;
case 2 -> {
int tmp = 50;
yield tmp * 2;
}
default -> 0;
};
Зачем нужно
switchвозвращает значение — не нужно временной переменной.Стрелочная форма не имеет fall-through — меньше багов.
Несколько меток через запятую:
case 1, 2, 3 ->.Компилятор требует обработать все случаи (exhaustive).
Пример 1. Switch как выражение
public class SwitchExpr {
public static void main(String[] args) {
int day = 3;
String name = switch (day) {
case 1 -> "Понедельник";
case 2 -> "Вторник";
case 3 -> "Среда";
case 4 -> "Четверг";
case 5 -> "Пятница";
case 6, 7 -> "Выходной";
default -> "Неверный день";
};
System.out.println("День " + day + ": " + name);
}
}
Output:
День 3: Среда
Пример 2. Несколько меток через запятую
public class SwitchMulti {
public static String season(int month) {
return switch (month) {
case 12, 1, 2 -> "Зима";
case 3, 4, 5 -> "Весна";
case 6, 7, 8 -> "Лето";
case 9, 10, 11 -> "Осень";
default -> throw new IllegalArgumentException("Неверный месяц: " + month);
};
}
public static void main(String[] args) {
for (int m : new int[] {1, 4, 7, 10}) {
System.out.println(m + " -> " + season(m));
}
}
}
Output:
1 -> Зима
4 -> Весна
7 -> Лето
10 -> Осень
Пример 3. Блок с yield
public class SwitchYield {
public static int complexLogic(int x) {
return switch (x) {
case 0 -> 0;
case 1 -> 1;
default -> {
int square = x * x;
int doubled = square * 2;
yield doubled + 1; // возвращает значение из блока
}
};
}
public static void main(String[] args) {
System.out.println("0 -> " + complexLogic(0));
System.out.println("1 -> " + complexLogic(1));
System.out.println("3 -> " + complexLogic(3));
System.out.println("5 -> " + complexLogic(5));
}
}
Output:
0 -> 0
1 -> 1
3 -> 19
5 -> 51
Пример 4. Switch по String
public class SwitchString {
public static int pinFor(String component) {
return switch (component) {
case "trig" -> 3;
case "echo" -> 7;
case "servo" -> 9;
case "ir" -> 17; // A3
case "bt-rx" -> 10;
case "bt-tx" -> 11;
default -> throw new IllegalArgumentException("Неизвестный компонент: " + component);
};
}
public static void main(String[] args) {
String[] parts = {"trig", "echo", "servo", "bt-rx"};
for (String p : parts) {
System.out.println(p + " -> D" + pinFor(p));
}
}
}
Output:
trig -> D3
echo -> D7
servo -> D9
bt-rx -> D10
Пример 5. Switch по enum (exhaustive)
public class SwitchEnum {
enum Direction { FORWARD, BACKWARD, LEFT, RIGHT, STOP }
public static String command(Direction d) {
// default не нужен — все варианты enum покрыты
return switch (d) {
case FORWARD -> "M F";
case BACKWARD -> "M B";
case LEFT -> "M L";
case RIGHT -> "M R";
case STOP -> "M S";
};
}
public static void main(String[] args) {
for (Direction d : Direction.values()) {
System.out.println(d + " -> " + command(d));
}
}
}
Output:
FORWARD -> M F
BACKWARD -> M B
LEFT -> M L
RIGHT -> M R
STOP -> M S
Пример 6. Старый vs новый стиль
public class SwitchOldVsNew {
// Старый стиль: оператор с break
public static String oldStyle(int n) {
String result;
switch (n) {
case 1:
result = "один";
break;
case 2:
result = "два";
break;
default:
result = "много";
}
return result;
}
// Новый стиль: выражение
public static String newStyle(int n) {
return switch (n) {
case 1 -> "один";
case 2 -> "два";
default -> "много";
};
}
public static void main(String[] args) {
for (int n : new int[] {1, 2, 5}) {
System.out.println(n + ": old=" + oldStyle(n) + ", new=" + newStyle(n));
}
}
}
Output:
1: old=один, new=один
2: old=два, new=два
5: old=много, new=много
Подводные камни
Предупреждение
В стрелочной форме
breakиспользовать нельзя — после стрелки идёт одно выражение или блок.В блоке возвращайте значение через
yield, а не черезreturn(returnвыйдет из метода целиком).Если
switchиспользуется как выражение, он обязан быть exhaustive: либоdefault, либо покрытие всех вариантов enum/sealed.Смешивать
case A:иcase A ->в одномswitchнельзя.case null(Java 21) нужно объявлять явно, иначеNullPointerException.
Совет
Если switch имеет более 2-3 веток и возвращает значение — используйте expression-форму. Код становится короче и безопаснее.
См. также
Примечание
Материал основан на официальной документации Oracle Java SE (docs.oracle.com/en/java/javase) и спецификации JEP 361 (openjdk.org/jeps/361), распространяемой под лицензией Oracle Free Documentation License. Тексты и примеры написаны заново для AlashEd Wiki.