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);
}
};