A Look at the New ‘Switch’ Expressions in Java 14

With many examples

Artem Smotrakov
Mar 7 · 4 min read
Photo by Karim MANJRA on Unsplash

Java 14 is going to be released on March 17, 2020. The new version of Java contains an interesting update to the Java language: new switch expressions. Let’s see how the new switch expressions can be used, what kind of advantages they offer, and what can potentially go wrong. In the end, we’ll tackle a tricky question about switch expressions.


The Classic ‘Switch’ Statement

You might have noticed many case and break statements in the example above. Those statements introduce some visual noise and make the code unnecessarily verbose. This visual noise may then mask mistakes such a missing break statement, which would mean accidental fall through.


The New ‘Switch’ Expressions

  • A new form of the switch label case ... ->, where only the code to the right of the label is going to be executed if the label is matched. The code to the right of a case ... -> label may be an expression, a block, or a throw statement.
  • A new yield statement to yield a value that becomes the value of the enclosing switch expression
  • Multiple constants per case that are separated by commas

With the new Java 14, it’s possible to use both traditional case ... : labels and the new case ... -> labels. It’s important the traditional labels still support fall through by default, but the new ones don't need to.

Let’s see how the example above can be rewritten with the new switch expressions:

This simple example can be compiled and run with just a single command (thanks to JEP 330, which has allowed the launching of single-file source-code programs since Java 11):

$ java WhoIsWho.java
Mozart was a composer
Dali was a painter
Dostoevsky was a writer

You can see several case statements have been merged, and the code doesn't use a break statement any more. As a result, the print() method became much shorter and looks nicer.

The following example shows a multiline default block that uses the new yield statement to yield a value. Note that there are several new constants in the Person enum that aren’t covered by the case labels in the switch expression:

Here’s what the program prints out:

$ java WhoIsWho.java 
Mozart was a composer
Dali was a painter
Oops! I don't know about Einstein
Einstein was a ...

The next example shows how factorial may be implemented with the new switch expressions:


Important Details

The first thing to know is the cases of a switch expression must be exhaustive. In other words, for all possible values, there must be a matching switch label. Let’s just add a new element to the enum and see what’s going to happen:

Compilation will fail right away with the following error message:

$ java InvalidWhoIsWho.java
InvalidWhoIsWho.java:19: error: the switch expression does not cover all possible input values
String title = switch (person) {
^
1 error
error: compilation failed

Adding a simple default case makes the Java compiler happy:

In general, unless an enum is used and the cases of a switch expression cover all constants, a default clause is required in the switch expression.

The second thing to remember is a switch expression must either complete normally with a value or by throwing an exception. Let’s take a look at the following code:

If we try to compile this code, the Java compiler will immediately complain:

InvalidSwitchExpressionWithoutDefault.java:8: error: the switch expression does not cover all possible input values
return switch (n) {
^
1 error
error: compilation failed

Again, adding a default case makes it work:

The third important thing to keep in mind is yield is now a restricted identifier. In particular, it means that classes named yield become illegal:

$ cat YieldClassName.java 
class yield {}
$ javac YieldClassName.java
YieldClassName.java:1: error: 'yield' not allowed here
class yield {
^
as of release 13, 'yield' is a restricted type name and cannot be used for type declarations
1 error
error: compilation failed

However, it’s allowed to use yield as a variable or a method name:

$ cat ValidUseOfYieldWord.java 
public class ValidUseOfYieldWord {
void yield() {
int yield = 0;
}
}
$ javac ValidUseOfYieldWord.java && echo ok || echo failed
ok

Conclusion

“These changes will simplify everyday coding.”

Let’s see.


Bonus

  1. Compilation error.
  2. Runtime error.
  3. Oops is printed out.
  4. OopsOops is printed out
  5. Forty-two is printed out.

Better Programming

Advice for programmers.

Thanks to Zack Shapiro

Artem Smotrakov

Written by

I write about Java and security

Better Programming

Advice for programmers.

More From Medium

More from Better Programming

More from Better Programming

More from Better Programming

The Zero-Dollar Infrastructure Stack

1.1K

More from Better Programming

More from Better Programming

Fun Side Projects That You Can Build Today

3.1K

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade