Java 14 introduced the concept of switch expressions as a way to simplify everyday coding. This was a preview language feature in JDK 12 and 13, and was delivered in JDK 14. This will also allow the eventual support of pattern matching in Java.
The traditional Java switch
statement is similar to that in C and C++. It supports fall-through behaviour by default. Fall-through is often useful for writing low-level code. However, if we forget a necessary break
statement it can result in unexpected and difficult to find errors. A break
statement after every case
block also makes our code verbose and appear repetitive.
The entire switch
block is treated as one scope. Any variables we create at any point inside the block will have scope until the end of the block. If we want to create temporary variables for a number of case
sections, each would need a different name. This could be somewhat annoying.
Switch Statement
Let’s say we have an enum
modelling the days of the week, and we want to print an appropriate message for each day. We could use the traditional switch
statement as follows:
// switch statement
switch (day) {
case MONDAY:
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
System.out.println("Slaving away over a hot computer...");
break;
case FRIDAY:
System.out.println("TGIF!");
break;
case SATURDAY:
System.out.println("Party Time!");
break;
case SUNDAY:
System.out.println("Relax and recover...");
break;
}
As we know, the existing switch
works only as a statement. Sometimes it could be useful to code it as an expression returning a value.
Switch Expression
JEP 361 extends the switch
keyword so it can be used as either a statement or an expression. Both allow either the traditional case ... :
labels (with fall-through) or the new case ... ->
labels (with no fall-through). There is also additional new syntax that can return a value from a switch
expression.
Using the new expression form of the switch
we can write the previous code as follows:
// switch expression
switch (day) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY
-> System.out.println("Slaving away over a hot computer...");
case FRIDAY -> System.out.println("TGIF!");
case SATURDAY -> System.out.println("Party Time!");
case SUNDAY -> System.out.println("Relax and recover...");
}
The code to the right of a case ... ->
label can only be an expression, a block, or a throw
statement.
Switch Expression Returning a Value
Let’s say that we decided to return a String
from the first code example instead of printing it directly. We would need to create a variable, and have every case
arm assign an appropriate value to it, as follows:
// switch statement
String message;
switch (day) {
case MONDAY:
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
message = "Slaving away over a hot computer...";
break;
case FRIDAY:
message = "TGIF!";
break;
case SATURDAY:
message = "Party Time!";
break;
case SUNDAY:
message = "Relax and recover...";
break;
default:
message = "Whoops!";
}
Using the switch
as an expression, the code is now safer and more obvious:
String message = switch (day) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY
-> "Slaving away over a hot computer...";
case FRIDAY -> "TGIF!";
case SATURDAY -> "Party Time!";
case SUNDAY -> "Relax and recover...";
};
Note the semi-colon after the switch
block. The switch
expression is now used in an assignment statement and needs the terminating semi-colon.
Yielding A Value
If we look at the previous code, each case
arm had a single expression to the right of the case ... ->
label. If we needed to execute a block of code instead of just using an expression, there is a new yield
statement:
String message = switch (day) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY
-> {
// lots of extra code to execute
String value = "Slaving away as usual...";
yield value;
};
case FRIDAY -> "TGIF!";
case SATURDAY -> "Party Time!";
case SUNDAY -> "Relax and recover...";
};
Ending Off
For more details on switch expressions, see https://openjdk.org/jeps/361
Don’t forget to share your comments and Java experiences.