Как часть Java SE 12, switch
выражения были введены, а начиная с Java SE 14 они были стандартизированы. Чем они отличаются от операторов switch
?
Что такое выражения переключения и чем они отличаются от операторов переключения?
Ответы (3)
Оператор switch
:
В отличие от оператора if/else if/else
, оператор switch
может иметь несколько возможных путей выполнения. switch
работает с примитивными типами byte
, short
, char
и int
, их соответствующими типами-оболочками (Byte
, Short
, Character
и Integer
), перечисляемыми типами и типом String
1. В то время как оператор if-else
используется для проверки выражений, основанных на диапазонах значений или условий, оператор switch
используется для проверки выражений, основанных только на одном значении.
Демо
enum PaymentStatus {
UNPAID, PARTPAID, PAID, DISPUTED, UNKNOWN;
}
public class Main {
public static void main(String[] args) {
String message = "";
PaymentStatus paymentStatus = PaymentStatus.PARTPAID;
switch (paymentStatus) {
case UNPAID:
message = "The order has not been paid yet. Please make the minimum/full amount to procced.";
break;
case PARTPAID:
message = "The order is partially paid. Some features will not be available. Please check the brochure for details.";
break;
case PAID:
message = "The order is fully paid. Please choose the desired items from the menu.";
break;
default:
throw new IllegalStateException("Invalid payment status: " + paymentStatus);
}
System.out.println(message);
}
}
Вывод:
The order is partially paid. Some features will not be available. Please check the brochure for details.
Выражение switch
:
Выражение switch
было введено в Java SE 12. Однако оно оставалось в качестве функции Preview в Java SE 12 и 13 и, наконец, было стандартизировано в Java SE 14. Как и любое выражение, switch
выражений дают одно значение и могут использоваться в операторах. Он также представил метки со стрелками case
, устраняющие необходимость в операторах break
для предотвращения провала. Начиная с Java SE 15, поддерживаемые типы данных не изменились (упомянутые в разделе операторов switch
выше).
Демо
enum PaymentStatus {
UNPAID, PARTPAID, PAID, DISPUTED, UNKNOWN;
}
public class Main {
public static void main(String[] args) {
PaymentStatus paymentStatus = PaymentStatus.PARTPAID;
String message = switch (paymentStatus) {
case UNPAID -> "The order has not been paid yet. Please make the minimum/full amount to procced.";
case PARTPAID -> "The order is partially paid. Some features will not be available. Please check the brochure for details.";
case PAID -> "The order is fully paid. Please choose the desired items from the menu.";
default -> throw new IllegalStateException("Invalid payment status: " + paymentStatus);
};
System.out.println(message);
}
}
Вывод:
The order is partially paid. Some features will not be available. Please check the brochure for details.
Выражение switch
с yield
:
Начиная с Java SE 13, вы можете использовать оператор yield
вместо оператора стрелки (-›), чтобы вернуть значение из выражения switch
.
Демо
enum PaymentStatus {
UNPAID, PARTPAID, PAID, DISPUTED, UNKNOWN;
}
public class Main {
public static void main(String[] args) {
PaymentStatus paymentStatus = PaymentStatus.PARTPAID;
String message = switch (paymentStatus) {
case UNPAID:
yield "The order has not been paid yet. Please make the minimum/full amount to procced.";
case PARTPAID:
yield "The order is partially paid. Some features will not be available. Please check the brochure for details.";
case PAID:
yield "The order is fully paid. Please choose the desired items from the menu.";
default:
throw new IllegalStateException("Invalid payment status: " + paymentStatus);
};
System.out.println(message);
}
}
Вывод:
The order is partially paid. Some features will not be available. Please check the brochure for details.
1 Поддержка String
была добавлена в JDK 7.
switch
может выполнять несколько случаев для одного переключателя. Если вы имеете в виду, что switch
поддерживает отказоустойчивость, было бы гораздо понятнее упомянуть об этом явно. Помимо этого, if/else if/else — это просто другой синтаксис по сравнению с оператором switch, потому что вы можете легко преобразовать любой оператор switch без провала в формат if/else if/else.
- person Mikko Rantalainen; 22.06.2021
Хорошая запись! Но я мог бы также добавить возможность иметь несколько вариантов для одного оператора case. Следующий пример очень надуманный (есть много лучших способов его достижения). Он просто подсчитывает частоту гласных, цифр, согласных и других символов в строке.
int count[] = new int[4];
String s = "829s2bi9jskj*&@)(so2i2ksso";
for (char c : s.toCharArray()) {
int i = switch (c) {
case 'a', 'e', 'i', 'o', 'u' -> 0;
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> 1;
case 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w',
'x', 'y', 'z' -> 2;
default -> 3;
};
count[i]++;
}
System.out.printf("vowels - %d%n", count[0]);
System.out.printf("digits - %d%n", count[1]);
System.out.printf("consonants - %d%n", count[2]);
System.out.printf("other - %d%n", count[3]);
Отпечатки
vowels - 4
digits - 7
consonants - 10
other - 5
Добавление к существующим ответам: yield
также можно использовать с ->
, и его основная цель - разрешить использование блока, когда одного выражения недостаточно для данного случая:
var test = switch (value) {
case A -> 1;
case B -> 2;
case C -> {
System.err.println("neither A nor B"); // or some calculation
yield -1;
}
}
Я бы также упомянул JEP-354, где предложено и описано выражение switch.
Формальную спецификацию, как всегда, можно найти в Спецификации языка Java.