# Switch to when

‘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 { and }. There is no break exists or required.

If 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 sealed classes. Compilation fails if a missing branch is detected.

Overall I turn the example into this:

Looks concise, isn’t it?

# Generated bytecode

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 againt updated 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 toString() or getClass().getName() were nice to have helpers. Still, in general, such calls may also throw exceptions.

# Conclusion

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