Working with Pattern Matching
1. Using Pattern Matching for instanceof (Java 16+)
| Form | Example |
|---|---|
| Type pattern | if (o instanceof String s) { ... use s ... } |
| Negated | if (!(o instanceof String s)) return; // s in scope after |
| Combined | if (o instanceof Integer i && i > 0) |
2. Using Switch Expressions (Java 14+)
| Feature | Detail |
|---|---|
| Arrow form | case A -> expr; |
| No fall-through | Each arrow is independent |
| Multi-label | case A, B -> ... |
yield | Block-form return value |
Example: Switch expression
int days = switch (month) {
case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;
case APR, JUN, SEP, NOV -> 30;
case FEB -> { yield isLeap ? 29 : 28; }
};
3. Using Pattern Matching in Switch (Java 21+)
| Pattern | Form |
|---|---|
| Type | case Integer i -> |
| Record | case Point(int x, int y) -> |
| Guarded | case Integer i when i > 0 -> |
| null | case null -> ... |
| Default | default -> |
4. Understanding Type Patterns
| Aspect | Detail |
|---|---|
| Binding | Pattern variable typed |
| Total pattern | Type pattern matches non-null |
| Generics | Erasure rules apply |
5. Using Guarded Patterns (when clause)
| Form | Behavior |
|---|---|
case T t when expr -> | Match only if expr true |
| Order | Earlier guards take precedence |
| Binding scope | Pattern var visible in guard |
Example: Guarded
String describe(Object o) {
return switch (o) {
case Integer i when i < 0 -> "negative";
case Integer i when i == 0 -> "zero";
case Integer i -> "positive: " + i;
case null, default -> "other";
};
}
6. Using Record Patterns (Java 21+)
| Form | Example |
|---|---|
| Flat | Point(int x, int y) |
| Nested | Line(Point(int x1, int y1), Point(int x2, int y2)) |
| Var inference | Point(var x, var y) |
7. Understanding Pattern Dominance
| Rule | Effect |
|---|---|
| Subtype before supertype | Compile error if reversed |
| Unguarded before guarded | Same dominance check |
| null label | Cannot be combined with type pattern unless null, default |
8. Using Null Patterns
| Form | Behavior |
|---|---|
| No null label | Switch throws NPE on null |
case null -> | Explicit null branch |
case null, default -> | Combined |
9. Understanding Exhaustiveness in Switch
| Type | Exhaustive Required? |
|---|---|
| Switch expression | Yes |
| Switch statement (arrow) | Yes if uses patterns |
| Sealed type | Permitted subtypes covered |
| Enum | All constants covered |
10. Combining Multiple Patterns
| Combinator | Use |
|---|---|
| Comma | case A, B -> share branch |
| Nested | Record patterns nest |
| Guard | Refine match further |
11. Using Deconstruction Patterns
| Pattern | Effect |
|---|---|
| Record pattern | Binds each component |
var in pattern | Infers component type |
| Nested record | Deep destructure |
Note: Deconstruction patterns for arbitrary classes are a preview feature in newer JDKs.