Pattern matching: instanceof, switch and record patterns
Pattern matching tests a value's shape and pulls out its parts in one step.
- instanceof patterns (final in Java 16):
if (obj instanceof String s), with no cast needed. - switch patterns (final in Java 21): switch on types, with guards (
when) andcase null. - Record patterns (final in Java 21): take a record apart right inside the pattern.
- Unnamed variables
_(final in Java 22) for the parts you don't need.
Combined with sealed interfaces, the compiler checks that every case is handled.
Old way vs new way
if (e instanceof Purchase) {
Purchase p = (Purchase) e;
if (p.amountInr() > 5000) return "Big sale: " + p.course();
return "Sale: " + p.course();
} else if (e instanceof Signup) {
return "Welcome mail to " + ((Signup) e).email();
}
// easy to forget a type: the compiler can't helpsealed interface Event permits Signup, Purchase, Refund {}
record Signup(String email) implements Event {}
record Purchase(String course, int amountInr) implements Event {}
record Refund(String course, int amountInr, String reason) implements Event {}
String describe(Event e) {
return switch (e) {
case Signup(var email) -> "Welcome mail to " + email;
case Purchase(var c, var amt) when amt > 5000 -> "Big sale: " + c;
case Purchase(var c, _) -> "Sale: " + c; // _ is Java 22+
case Refund(var c, var amt, _) -> "Refund " + amt + " for " + c;
};
}
Object o = 42;
if (o instanceof Integer i && i > 40) { // Java 16+
System.out.println(i + 1);
}Common mistake
Adding a default branch to a switch over a sealed type. It compiles, but you lose the compile error that would tell you when someone adds a new subtype.
Under the hood
Pattern cases are checked for dominance: putting a broad case (case Purchase p) before a narrower guarded one is a compile error. Primitive type patterns (case int i when i > 0) have been in preview since Java 23, now in their fifth preview in Java 27. This style is Java's take on algebraic data types, familiar from Scala and Kotlin.
Check yourself
Which version made pattern matching for switch final?
How this connects
Where this leads
You've reached the end of this thread. Try a learning path for what's next.
Part of Upgrade from Java 8 to Java 25.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.