Medium java java-21

What is pattern matching for switch?

The 30 second answer

Final in Java 21, switch cases can match on types instead of only constants, with guards using when, and a case for null. Combined with record patterns, also final in 21, a case can take a record apart into its components directly. Over a sealed type, the compiler checks every subtype is covered, so I get type-safe branching without instanceof chains or the visitor pattern.

sealed interface Shape permits Circle, Square {}
record Circle(double r) implements Shape {}
record Square(double side) implements Shape {}

String describe(Shape s) {
    return switch (s) {
        case Circle c when c.r() > 10 -> "big circle";
        case Circle c                 -> "circle";
        case Square(double side)      -> "square " + side;   // record pattern
    };
}

String fmt(Object o) {
    return switch (o) {
        case null      -> "null";
        case Integer i -> "int " + i;
        case String s  -> "text " + s;
        default        -> o.toString();
    };
}

Rules: more specific cases must come before general ones (the compiler rejects dominated labels). Without case null, a null selector still throws NullPointerException, as before. Record patterns can be nested, e.g. case Line(Point(var x1, var y1), Point p2).

Pattern matching for switch was previewed in Java 17 to 20 and became final in Java 21, together with record patterns (previewed in 19 and 20).

Sources: JEP 441: Pattern Matching for switch, JEP 440: Record Patterns

Sources (0)
See inline citations in the answer above.