‘when’ expression in Kotlin VS ‘switch’ statement in Java
Switch in Java
Consider the following code in Java
Widespread pattern, isn’t it? There are several things wrong with it! First,
Foo f variable is not final,
so it can be ocassionally changed in the future after some code changes.
Next, we switll have
default branch which is not necessary as we cover all enum values. But if
someone dares to add extra enum value, this code will still compile correctly!
Enough problems? Nope! I forgot
break; in each
case branch. Surprise.
An improvement is still possible to solve some of the problems above. Use
return statement! So we have
Is it better now? More or less yes. But would you create an additional function for every
switch? I’m not sure.
When in Kotlin
The equivalent constuction to
switch in Java is
when in Kotlin. You may take a look to the
when expression documentation
for more details. Note,
when expression is more functional than
switch in Java.
This was just one-to-one conversion to Kotlin and I see the warning to convert
var f to
val f at first.
It is good to notice,
when can be used as expression! We may avoid assigning
f variable inside each case.
The right of
-> is also an expression. If you need more things to do, use
}. There is no
exists or required.
when is used as expression,
else branch is not necessary, the compiler can prove all branches are included.
At least this works if you checking enum or
Compilation fails if a missing branch is detected.
Overall I turn the example into this:
Looks concise, isn’t it?
Let’s look into bytecode for the
when statement call. Note. I use IntelliJ IDEA 2017.1 EAP with Kotlin
1.0.6 plugin. The generated bytecode may change with a future version of tools.
From the bytecode we see it throws
kotlin/NoWhenBranchMatchedException in case it turned out
there is an additional case. For example, this may happen if we are running a compiled code
Bar enum with additional case added.
Still, a re-compilation will show there is an errors.
The only problem is that
NoWhenBranchMatchedException contains no information on what
kind of instance was there, maybe a
getClass().getName() were nice to
have helpers. Still, in general, such calls may also throw exceptions.
In this post we see how
when expression can help one avoid trivial errors
in switches. We discussed the benefit of using
when as expression