Pattern Matching
TL;DR
- Pattern Matching is a feature introduced gradually in Modern Java (Java 16+) to simplify data extraction and type checking.
- It removes the tedious boilerplate of checking a type (
instanceof) and immediately casting it to a new variable. - It enables powerful data-oriented programming techniques when combined with Records and Sealed Classes.
Concept
In traditional object-oriented Java, if you are given an unknown Object obj, you have to figure out what it is and cast it:
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
This is redundant. You just verified it is a String; why do you have to tell the compiler to cast it to a String on the very next line?
Pattern Matching solves this by combining the test (instanceof) and the extraction (creating the variable s) into a single operation. The compiler handles the casting invisibly, making code safer and much more readable.
Examples
// 1. Pattern Matching for instanceof (Java 16)
public void process(Object obj) {
// Tests if obj is a String, and if so, safely casts it to the variable 's'
if (obj instanceof String s) {
System.out.println("String length: " + s.length());
} else if (obj instanceof Integer i) {
System.out.println("Integer value: " + i);
}
}
// 2. Pattern Matching with logical operators
public void processString(Object obj) {
// The variable 's' is immediately available in the right-hand side of the && operator!
if (obj instanceof String s && s.length() > 5) {
System.out.println("Long string: " + s);
}
}
Interview Questions
Q: What is the scope of a pattern variable (like s in the example)?
A: The scope of a pattern variable is strictly limited to the block of code where the compiler can guarantee the pattern matched successfully. This is called “Flow Scoping.”
If you write if (obj instanceof String s) { ... }, s is only available inside the if block.
Interestingly, if you write if (!(obj instanceof String s)) { return; }, the variable s is actually available after the if block, because the compiler knows that if the program didn’t return, obj is definitively a String!
Q: What are Record Patterns (Java 21)?
A: Record Patterns take pattern matching to the next level by allowing you to deconstruct a Record into its individual components instantly.
Instead of: if (obj instanceof Point p) { int x = p.x(); int y = p.y(); }
You can write: if (obj instanceof Point(int x, int y)) { System.out.println(x + y); }. This extracts the x and y variables directly without ever needing to reference the Point object itself.