The <code>instanceof</code> Operator in Java
instanceof tests whether a reference points to an object of a given type (or a subtype). It returns true for null? No β null instanceof X is always false. Since Java 16, instanceof also declares a variable of the matched type.
Classic syntax
Object o = "hello";
if (o instanceof String) {
String s = (String) o; // cast needed
System.out.println(s.length());
}
Pattern matching (Java 16+)
if (o instanceof String s) { // declares `s`, bound only in true branch
System.out.println(s.length());
}
if (o instanceof String s && s.length() > 0) {
... // `s` usable here
}
The variable is only in scope where the test is known to be true. It's implicitly final.
Pattern matching for switch (Java 21+)
String describe(Object o) {
return switch (o) {
case Integer i when i > 0 -> "positive int";
case Integer i -> "non-positive int";
case String s -> "string of " + s.length();
case null -> "null";
default -> "unknown";
};
}
instanceof vs getClass()
Object o = new Dog();
o instanceof Animal; // true β subclass relationship
o.getClass() == Animal.class; // false β exact class only
Use instanceof for "is-a" checks (including subclasses). Use getClass() only if you need exact-class equality, typically in a rigorous equals implementation.
Generics and instanceof
// β can't test a generic type at runtime (type erasure)
if (x instanceof List<String>) // compile error
// β
test the raw shape
if (x instanceof List<?> list) // OK β use wildcards
Common mistakes
- Cascades of
if / else ifwithinstanceofβ often a sign that polymorphism would be cleaner. But when you truly need to handle many external types (events, messages), pattern-matchingswitchis the right tool. - Not checking before cast β
(String) othrowsClassCastExceptionat runtime. - Mixing
instanceofwith==on primitives βinstanceofonly works on references.
Related
Pillar: Java keywords. See also instanceof operator, ClassCastException.