Switch your expressions with the Java 14 ‘switch’

Light & Wonder Tech Blog
5 min readMay 19, 2023

By Pallavi Sonal, Manager, Software Engineering, Light & Wonder

Pallavi Sonal, Manager, Software Engineering, Light & Wonder
Pallavi Sonal, Manager, Software Engineering, Light & Wonder

Like most of us in the Java world, I, too, am still on Java 8! With my love for Java somewhat getting buried deep in the daily grind, I only took the time to check out some interesting new features introduced post-Java 8.

At the beginning of this year, relaxing in the warm winter sun with hot tea, I took the resolution to revive this love and started leafing over what’s new from Java 9 to Java 19.

This article, and the later ones to come in the series, is an attempt to share what caught my eye. This one is about the way our classic old ‘switch’ has evolved with Java 14. All examples used here can be found in my GitHub repository

The proposal introducing changes to ‘switch’ started with JDK 12 as a preview feature, was refined in JDK 13 again as a preview feature, and finally became a fully baked permanent feature in JDK 14.

Here is how we have been using the ‘switch’ statement:

The above example intends to demonstrate the ‘fall through’ semantics of the classic ‘switch.’ The first few ‘case’ statements do not have anything to execute after the colon, so the execution keeps on falling through the next and the next one until it encounters a ‘break.’ Doesn’t this look too noisy with unnecessary repetition? What if we accidentally miss out on the ‘break’ statement in the DECEMBER block? There will be confusion about whether the month has 31 or 30 days, as both will be printed as the output.

Here is how we can now write it in a cleaner way from Java 14 onwards:

Now this sure looks better! Multiple constants are allowed as labels for each ‘case’ and must be separated by a comma. I know you are saying, “Hey! This still has the ‘fall through’ until we reach break; we can still miss a ‘break’ and cause unnecessary trouble in debugging. “ So, here comes the good old ‘lambda arrow’ which we all from JDK 8 world are so familiar with, and I can write the above code as:

Much better now? With ‘case <label> ->, ‘if the label is matched, only the statement or expression to the right of the ‘->’ will be executed, and there will be no fall through.’ No tension of missing ‘break’ and accidental ‘fall through’! And if we have multiple statements in the ‘case’ branch, a block {} can be created. This means that if we want to introduce a local variable in a branch, its scope will be limited to that branch. Whereas, in our classic ‘switch,’ the scope of a local variable is the entire ‘switch’ block.

Now that we are halfway through, I will reveal the reason why the odd creativity with the title of this article. With JDK 14, the ‘switch’ statement can also be used as an expression. You would have got a hint of this when I mentioned the lambda arrow above. This ‘->’ basically tells the compiler that a value is returned for the ‘switch’ expression, a kind of implicit ‘return.’ And that is the reason the execution breaks out of the ‘switch,’ and there is no reason to have the ‘break’ statement. So, the above code can be modified keeping all this in mind:

If the expression to the right of ‘case <label> ->’ is a full block and returns a value, then it is said to be yielding a value, and it is expressed with the new ‘yield’ statement as used in the below snippet:

Using the ‘switch’ as the expression doesn’t necessitate using a lambda arrow; instead, the traditional one with a colon can also be used as an expression, yielding a value using the ‘yield’ statement. Whether a ‘break’ is used to come out of the ‘switch’ or a ‘yield’ is used for that purpose tells us if it is a ‘switch’ statement or a ‘switch’ expression. ‘yield’ is not a keyword but a restricted identifier, so this means we should not create a class with name ‘yield’ and be cautious while using as a method or variable name so that it does not create an ambiguity with ‘yield’ statement.

One very important requirement for using ‘switch’ as an expression is exhaustiveness. This means there should be a ‘case’ label for each possible value of the ‘switch’ variable. This can generally be taken care of by using a ‘default’ clause. When we use an ‘enum,’ and the switch expression covers all the constants of the ‘enum,’ an explicit ‘default’ clause will be unnecessary. The compiler also makes sure to check that for a ‘switch’ expression, every ‘case’ branch either yields a value or throws an exception.

All these changes that have been made to ‘switch’ are a preparation for more to come. ‘Pattern Matching,’ which is still a preview feature, is one such change to look forward to when it comes to ‘switch’ expressions.

So, did these changes in the JDK ‘switch’ switch your expression to joy or worry? Please do comment.

The opinions expressed in this blog post are strictly those of the author in their personal capacity. They do not purport to reflect the opinions or views of Light & Wonder or of its employees.

WE’RE HIRING

Find out more about life at Light & Wonder and the roles we are looking to fill: https://www.lnw.com/careers

--

--