Unravel โบ Java concepts โบ OOP and types
Pattern matching with instanceof
if (o instanceof String s) tests the type and gives you a ready-cast variable s in one step.
Learn these first
At a glance
A security guard who not only checks "are you a courier?" but also hands you the courier badge to wear for the rest of the visit.
- 1Old style: if (o instanceof String) { String s = (String) o; ..}. New style: if (o instanceof String s) { ... s.length() ... }. No cast, no repeated type.
- 2The variable s exists only where the compiler can prove the test succeeded: inside the if, or after an early exit such as if (!(o instanceof String s)) return;
- 3Record patterns deconstruct a record and match nested types in one go: if (shape instanceof Line(Point(var x1, var y1), Point p2))
- 4The same patterns work in switch cases, with when guards: case Integer i when i > 10 -> ...
- instanceof is false for null, so a pattern never matches null: no NullPointerException from the test itself
- Long chains of instanceof are a smell in object-oriented code: usually a method on the type (polymorphism) or a sealed type with a switch is cleaner
- The compiler translates a pattern into the same instanceof and checkcast instructions as before plus a local variable; record patterns call the record's accessor methods in sequence, so any exception inside an accessor surfaces as a MatchException
public class Describer { static String describe(Object o) { if (o instanceof String s && !s.isEmpty()) return "text of " + s.length(); if (o instanceof Integer i) return "number " + (i + 1); return "something else"; }}Read the full explanation (about 1 min)
if (o instanceof String s) tests the type and gives you a ready-cast variable s in one step. Record patterns go further and take an object apart: o instanceof Point(int x, int y).
A mental model
A security guard who not only checks "are you a courier?" but also hands you the courier badge to wear for the rest of the visit.
How it works
Old style: if (o instanceof String) { String s = (String) o; ... }. New style: if (o instanceof String s) { ... s.length() ... }. No cast, no repeated type.
The variable s exists only where the compiler can prove the test succeeded: inside the if, or after an early exit such as if (!(o instanceof String s)) return;.
Record patterns deconstruct a record and match nested types in one go: if (shape instanceof Line(Point(var x1, var y1), Point p2)).
The same patterns work in switch cases, with when guards: case Integer i when i > 10 -> ....
Going deeper
instanceof is false for null, so a pattern never matches null: no NullPointerException from the test itself.
Long chains of instanceof are a smell in object-oriented code: usually a method on the type (polymorphism) or a sealed type with a switch is cleaner. Patterns are best at the boundary, for example in equals or when handling mixed data.
Under the hood
The compiler translates a pattern into the same instanceof and checkcast instructions as before plus a local variable; record patterns call the record's accessor methods in sequence, so any exception inside an accessor surfaces as a MatchException.
Common mistakes
- Using the pattern variable outside its scope.
- Reassigning the pattern variable and confusing readers.
- Replacing a clean polymorphic method call with a chain of instanceof tests.
How Unravel recognises it
When you paste code, Unravel looks for these signs of pattern matching with instanceof. Spotting them yourself is a good habit when you read unfamiliar code:
- Language constructs:
instanceof-patternrecord-patterntype-pattern
Part of a learning path
- Modern Java syntax ยท previous: Sealed classes and interfaces ยท next: Wildcards and bounded generics
Related concepts
Frequently asked questions
What is Pattern matching with instanceof?
if (o instanceof String s) tests the type and gives you a ready-cast variable s in one step. Record patterns go further and take an object apart: o instanceof Point(int x, int y).
What are the most common mistakes with Pattern matching with instanceof?
Using the pattern variable outside its scope. Reassigning the pattern variable and confusing readers. Replacing a clean polymorphic method call with a chain of instanceof tests.
How can I see Pattern matching with instanceof in real code?
Paste your own Java into Unravel and it will point out where pattern matching with instanceof appears, explain how it works at the detail level you choose, and draw the flow of the code around it.