The <code>instanceof</code> Operator in Java
instanceof is a binary operator that returns true if its left-hand reference points to an object that is an instance of the right-hand type (or a subtype). It's a runtime check β so it sees the actual class of the object, not the declared type of the variable.
Classic form
Object o = "hello";
if (o instanceof String) {
String s = (String) o; // cast after the check
System.out.println(s.length());
}
Pattern matching (Java 16+)
if (o instanceof String s) { // declares `s`, only in scope where true
System.out.println(s.length());
}
The binding variable is implicitly final and only visible in the true branch (and in expressions logically guarded by the test).
Null safety
String s = null;
s instanceof String; // false β always. No NullPointerException.
Subtype relationship
Object o = new ArrayList<>();
o instanceof List; // true β ArrayList implements List
o instanceof Collection; // true β List extends Collection
o instanceof String; // false
Generics and instanceof
Due to type erasure, you can't check a parameterised type at runtime:
if (x instanceof List<String>) // β compile error
if (x instanceof List<?> list) // β
wildcard is fine
When instanceof is a smell
If your code is a ladder of instanceof checks on one hierarchy, consider polymorphism β a virtual method on the base type is usually cleaner. Pattern matching for switch (Java 21+) makes the remaining legitimate cases concise.
Common mistakes
- Casting without checking β
(String) othrowsClassCastExceptionat runtime. - Forgetting null β an extra null-check before
instanceofis redundant;null instanceof Xis alwaysfalse. - Using
getClass()when you wantinstanceofβgetClass() == X.classdoesn't match subclasses.
Related
Pillar: Java operators. See also instanceof keyword, ClassCastException.