crush depth

JDK 21

Like many people, I've been waiting for JDK 21 for a long time. Now that Eclipse Temurin has JDK 21 builds, I'm finally now starting the push to upgrade all of my projects to JDK 21.

Primarily, I'm interested in pattern matching for my existing code. I wrote an article back in 2016 investigating the various ways that people have implemented algebraic data types on the JVM.

Since then, sealed classes have been added to the JVM. Sealed classes allow for specifying that a group of classes form a closed set, and the compiler can then reason about the set as a whole. Unfortunately, up until JDK 21, there was effectively no way to safely pattern match on a value of a sealed class. The old way to do this was via the visitor pattern, which frankly noone would have done by choice if there'd been any other alternative.

Knowing that pattern matching was due to become a first-class language feature (but didn't know exactly when), I've been writing code that looks like this for the past couple of years:

    if (message instanceof final NPACommandType<?> command) {
      return toWireCommand(command);
    if (message instanceof final NPAResponseType response) {
      return toWireResponse(response);
    if (message instanceof final NPAEventType event) {
      return toWireEvent(event);
    throw new IllegalStateException();

Why write this kind of obviously-fragile code? My reasoning was that there would be a more direct migration path from this kind of if-then-else over sealed classes than there would be had I made every single class I wanted to match on implement a visitor. I'm hoping that Intellij IDEA will offer to convert the above code into an exhaustive switch statement when I set the language level to JDK 21. Time will tell!