Disassembling Java 13 Switch Expressions
In Java 13 there’s an experimental feature called switch expressions introduced by JEP-354. It basically allows you to write a switch block as if it were an expression:
void expr() {
int i = (int)(Math.random() * 2);
String s = switch (i) {
case 1 -> "one";
case 2 -> "two";
default -> "other";
};
System.out.println(s);
}
See how the result of the switch is directly assigned, shortening the block and eliminating the requirement of break?
One might say it is just (very nice) syntactic sugar, similar to Kotlin’s when expression. But, is it? Let’s find out what byte code the compiler produces for a plain old Java switch block v.s. the new switch expression.
Let’s take the following 2 methods:
The one using Java 13’s switch expression is clearly shorter to write and easier to read, but what does the byte code look like?
Compiling and Disassembling
Since switch expressions are an experimental feature in Java 13 you have to provide the –enable-preview flag to the compiler. After compilation, we can use JDK’s disassembler (javap) to find out what the byte code looks like:
For the plain old Java switch block this gives the following output:
The Java 13 switch expression looks the following:
The generated byte code looks very much alike but the switch branch handling differs. The handling of a switch block branch works like this:
Byte code | Explanation |
---|---|
ldc | Push constant (our string) to the stack |
astore_2 | Store reference in local variable 2 |
goto 51 | Jump to ‘line’ 51 |
(line 51..n) | Invoke System.out.println |
Handling of our switch expressions branches looks like this:
Byte code | Explanation |
---|---|
ldc | Push constant (our string) to the stack |
goto 48 | Jump to ‘line’ 48 |
(line 48) astore_2 | Store reference in local variable 2 |
(line 49..n) | Invoke System.out.println |
The difference is that in a switch block, the value is stored (astore_2) in each branch, whereas when using a switch expression the resulting value is stored ‘at the end’ after jumping out of the switch. That’s exactly what you’d expect when reading the Java source, which surprised me since generated byte code often differs quite a bit from its Java source.
Conclusion
Although the differences are minor the byte code is different, so Java 13’s switch expressions are more than just syntactic sugar.
Either way, I’m very happy that we can now write Kotlin-esque switch expressions.