35. Pattern Matching in Switch
Pattern matching for switch (Java 21) allows matching on types, records, and guarded patterns (when), with null handling and full exhaustiveness checking over sealed types.
Explanation
Pattern matching in switch (JEP 441, Java 21 standard) allows case labels to be type patterns (case String s), guarded patterns (case Integer i when i > 0), and record deconstruction patterns (case Point(int x, int y)).
The switch must be exhaustive: for sealed types, covering all permitted subtypes is enough (no default); for unsealed types like Object, a default or case null + handling is required.
null handling: by default, passing null to a switch throws NullPointerException. You can explicitly handle it with case null -> or case null, default -> to make null safe.
Guarded patterns with when replace the old if check inside a case body and make intent explicit at the pattern level. Order matters: more specific patterns must come before more general ones.
Example
public class PatternMatchingSwitch {
sealed interface Expr permits Num, Add, Mul, Neg {}
record Num(double val) implements Expr {}
record Add(Expr left, Expr right) implements Expr {}
record Mul(Expr left, Expr right) implements Expr {}
record Neg(Expr expr) implements Expr {}
static double eval(Expr e) {
return switch (e) {
case Num(var v) -> v;
case Add(var l, var r) -> eval(l) + eval(r);
case Mul(var l, var r) -> eval(l) * eval(r);
case Neg(var inner) -> -eval(inner);
};
}
static String classify(Object obj) {
return switch (obj) {
case null -> "null";
case Integer i when i < 0 -> "negative int: " + i;
case Integer i when i == 0 -> "zero";
case Integer i -> "positive int: " + i;
case String s when s.isEmpty() -> "empty string";
case String s -> "string: " + s;
default -> "other: " + obj.getClass().getSimpleName();
};
}
public static void main(String[] args) {
// Eval: (2 + 3) * -(4)
Expr expr = new Mul(new Add(new Num(2), new Num(3)), new Neg(new Num(4)));
System.out.println("Result: " + eval(expr)); // -20.0
// Pattern matching switch with guards
for (Object o : new Object[]{ null, -5, 0, 42, "", "hello", 3.14 }) {
System.out.println(classify(o));
}
}
}Sources
- https://openjdk.org/jeps/441 โ JEP 441: Pattern Matching for switch (standard, Java 21)
- https://dev.java/learn/pattern-matching/switch/ โ Pattern matching switch guide