3 Switch Expressions
Java SE 12 introduced switch expressions, which (like all
expressions) evaluate to a single value, and can be used in statements. It also introduced
"arrow case" labels that eliminate the need for break
statements to prevent fall through. Based on developer feedback on this feature, Java SE 13
introduces one change to switch expressions: To specify their value, use
the new yield statement instead of the break
statement.
Note:
This is a preview
feature, which is a feature whose design,
specification, and implementation are complete,
but is not permanent, which means that the feature
may exist in a different form or not at all in
future JDK releases. To compile and run code that
contains preview features, you must specify
additional command-line options. See Preview Features. For background information about the design of switch
expressions, see JEP 354.
Consider the following switch statement that prints the number of letters of
a day of the week:
public enum Day { SUNDAY, MONDAY, TUESDAY,
WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; }
// ...
int numLetters = 0;
Day day = Day.WEDNESDAY;
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numLetters = 6;
break;
case TUESDAY:
numLetters = 7;
break;
case THURSDAY:
case SATURDAY:
numLetters = 8;
break;
case WEDNESDAY:
numLetters = 9;
break;
default:
throw new IllegalStateException("Invalid day: " + day);
}
System.out.println(numLetters);It would be better if you could "return" the length of the day's name instead
of storing it in the variable numLetters; you can do this with a
switch expression. Furthermore, it would be better if you didn't
need break statements to prevent fall through; they are laborious to
write and easy to forget. You can do this with a new kind of case
label. The following is a switch expression that uses the new kind of
case label to print the number of letters of a day of the week:
Day day = Day.WEDNESDAY;
System.out.println(
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default -> throw new IllegalStateException("Invalid day: " + day);
}
); The new kind of case label has the following form:
case label_1, label_2, ..., label_n -> expression;|throw-statement;|block When the Java runtime matches any of the labels to the left of the arrow, it
runs the code to the right of the arrow and does not fall through; it does not run any
other code in the switch expression (or statement). If the code to the
right of the arrow is an expression, then the value of that expression is the value of
the switch expression.
You can use the new kind of case label in
switch statements. The following is like the first example, except
it uses "arrow case" labels instead of "colon case"
labels:
int numLetters = 0;
Day day = Day.WEDNESDAY;
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> numLetters = 6;
case TUESDAY -> numLetters = 7;
case THURSDAY, SATURDAY -> numLetters = 8;
case WEDNESDAY -> numLetters = 9;
default -> throw new IllegalStateException("Invalid day: " + day);
};
System.out.println(numLetters);You can use "colon case" labels in switch
expressions:
Day day = Day.WEDNESDAY;
int numLetters = switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
System.out.println(6);
yield 6;
case TUESDAY:
System.out.println(7);
yield 7;
case THURSDAY:
case SATURDAY:
System.out.println(8);
yield 8;
case WEDNESDAY:
System.out.println(9);
yield 9;
default:
throw new IllegalStateException("Invalid day: " + day);
};
System.out.println(numLetters);Java SE 13 introduces the yield statement. It takes one
argument, which is the value that the case label produces in a
switch expression.
The yield statement makes it easier for you to differentiate between
switch statements and switch expressions. A
switch statement, but not a switch expression, can
be the target of a break statement. Conversely, a
switch expression, but not a switch statement, can
be the target of a yield statement.
Note:
It's recommended that you use "arrow case" labels. It's
easy to forget to insert break or yield statements
when using "colon case" labels; if you do, you might introduce
unintentional fall through in your code.
For "arrow case" labels, to specify multiple statements
or code that are not expressions or throw statements, enclose them
in a block. Specify the value that the case label produces with the
yield statement:
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> {
System.out.println(6);
yield 6;
}
case TUESDAY -> {
System.out.println(7);
yield 7;
}
case THURSDAY, SATURDAY -> {
System.out.println(8);
yield 8;
}
case WEDNESDAY -> {
System.out.println(9);
yield 9;
}
default -> {
throw new IllegalStateException("Invalid day: " + day);
}
};