Until JDK 12, a switch could only be used as a statement, where it performed an action but did not return a result. In JDK 12, a switch can now be used as an expression, meaning it returns a result that can be assigned to a variable. There were also several changes to the syntax of case statements within the switch. Let's use the example from the JEP to understand how this works.
A common idiom of using switch is to use one variable to determine how to assign a value to another variable.
In this example, we're using the value of
Secondly, we must make an assignment in each case label group. In this case, we would get a compiler error if we forgot, but it is still not ideal. Our code is also quite verbose since each value of
Using the new case-statement syntax, we get much cleaner, less error-prone code:
Now, we need to make the assignment only once (from the return value of the switch expression) and can use a comma-separated list for the case labels. Since we don't use a break statement, we also eliminate the problem of fall-through.
The syntax of the switch expression allows the use of the older-style syntax so, in JDK 12, we can write it like this:
Feedback from the Java community indicated that overloading the use of the break to indicate the value to return could be confusing. The Java language also allows the use of break (and continue) with a label to perform a form of goto. JEP 354 changes the use of break, in this case, to yield, so in JDK 13, our code becomes:
Here, we can see the benefit of preview features that allow a change like this to be made easily before committing the syntax to the standard.
A common idiom of using switch is to use one variable to determine how to assign a value to another variable.
int numberOfLetters;
switch(dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numberOfLetter = 6;
break;
case TUESDAY
numberOfLetter = 7;
break;
case THURSDAY
case SATURDAY
numberOfLetter = 8;
break;
case WEDNESDAY
numberOfLetter = 9;
break;
default:
throw new IllegalStateException("Huh?: " + day);
}
In this example, we're using the value of
dayOfWeek
to assign a value to numberOfLetters
. Because of the way the switch statement works, the code is more error-prone than is ideal. Firstly, if we neglect to include a break statement for each case label group, the default is to fall-through to the next label group. This can lead to some subtle and hard to find bugs. Secondly, we must make an assignment in each case label group. In this case, we would get a compiler error if we forgot, but it is still not ideal. Our code is also quite verbose since each value of
dayOfWeek
must have its own case label.Using the new case-statement syntax, we get much cleaner, less error-prone code:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default -> throw new IllegalStateException("Huh?: " + day);
};
Now, we need to make the assignment only once (from the return value of the switch expression) and can use a comma-separated list for the case labels. Since we don't use a break statement, we also eliminate the problem of fall-through.
The syntax of the switch expression allows the use of the older-style syntax so, in JDK 12, we can write it like this:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
break 6;
case TUESDAY
break 7;
case THURSDAY
case SATURDAY
break 8;
case WEDNESDAY
break 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
Feedback from the Java community indicated that overloading the use of the break to indicate the value to return could be confusing. The Java language also allows the use of break (and continue) with a label to perform a form of goto. JEP 354 changes the use of break, in this case, to yield, so in JDK 13, our code becomes:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
yield 6;
case TUESDAY
yield 7;
case THURSDAY
case SATURDAY
yield 8;
case WEDNESDAY
yield 9;
default:
throw new IllegalStateException("Huh?: " + day);
};