instanceof Operator
Type checking at runtime
5 min read
instanceof Operator in Java
The instanceof operator tests whether an object is an instance of a specific class or implements an interface. Returns boolean.
Syntax & Behavior
obj instanceof ClassName→ true/false- Checks the actual runtime type
- Returns true for parent classes too
- null instanceof X is always false
- Java 16+ has pattern matching instanceof
💡 Java 16+: Pattern matching: if (obj instanceof String s) - automatically casts to s!
Code Examples
Basic instanceof checks
java
1// Basic instanceof Usage
2class Animal {}
3class Dog extends Animal {}
4class Cat extends Animal {}
5
6Animal animal = new Dog();
7
8// Check type at runtime
9System.out.println(animal instanceof Dog); // true
10System.out.println(animal instanceof Animal); // true
11System.out.println(animal instanceof Cat); // false
12System.out.println(animal instanceof Object); // true
13
14// null check
15Animal nullAnimal = null;
16System.out.println(nullAnimal instanceof Animal); // false (null is never instanceof)
17
18// Safe casting pattern
19if (animal instanceof Dog) {
20 Dog dog = (Dog) animal; // Safe - we checked first
21 dog.bark();
22}Pattern matching instanceof (Java 16+)
java
1// Pattern Matching instanceof (Java 16+)
2
3// Before Java 16 - verbose
4if (obj instanceof String) {
5 String s = (String) obj; // Manual cast
6 System.out.println(s.length());
7}
8
9// Java 16+ - Pattern matching
10if (obj instanceof String s) { // Automatic cast to 's'
11 System.out.println(s.length()); // Use s directly!
12}
13
14// Works with else too
15if (obj instanceof String s) {
16 System.out.println("String: " + s.toUpperCase());
17} else if (obj instanceof Integer i) {
18 System.out.println("Integer: " + (i * 2));
19} else if (obj instanceof Double d) {
20 System.out.println("Double: " + d);
21}
22
23// Negation pattern
24if (!(obj instanceof String s)) {
25 return; // Early return if not String
26}
27// s is in scope here!
28System.out.println(s.length());instanceof with interfaces
java
1// instanceof with Interfaces
2interface Flyable {
3 void fly();
4}
5
6interface Swimmable {
7 void swim();
8}
9
10class Bird implements Flyable {
11 public void fly() {
12 System.out.println("Bird flying");
13 }
14}
15
16class Duck implements Flyable, Swimmable {
17 public void fly() { System.out.println("Duck flying"); }
18 public void swim() { System.out.println("Duck swimming"); }
19}
20
21public void processAnimal(Object obj) {
22 if (obj instanceof Flyable flyer) {
23 flyer.fly();
24 }
25
26 if (obj instanceof Swimmable swimmer) {
27 swimmer.swim();
28 }
29
30 // An object can match multiple
31 if (obj instanceof Duck duck) {
32 // duck can both fly and swim
33 duck.fly();
34 duck.swim();
35 }
36}
37
38processAnimal(new Bird()); // Bird flying
39processAnimal(new Duck()); // Duck flying, Duck swimming, Duck flying, Duck swimmingequals() and switch patterns
java
1// equals() Implementation with instanceof
2public class Person {
3 private String name;
4 private int age;
5
6 @Override
7 public boolean equals(Object obj) {
8 // Pattern matching makes this cleaner (Java 16+)
9 if (obj instanceof Person other) {
10 return this.age == other.age &&
11 Objects.equals(this.name, other.name);
12 }
13 return false;
14
15 // Traditional way (pre-Java 16)
16 // if (!(obj instanceof Person)) return false;
17 // Person other = (Person) obj;
18 // return this.age == other.age && Objects.equals(this.name, other.name);
19 }
20}
21
22// Switch with Pattern Matching (Java 21+)
23public String describe(Object obj) {
24 return switch (obj) {
25 case String s -> "String of length " + s.length();
26 case Integer i -> "Integer: " + i;
27 case Double d -> "Double: " + d;
28 case int[] arr -> "Int array of length " + arr.length;
29 case null -> "null value";
30 default -> "Unknown type";
31 };
32}Use Cases
- Safe downcasting
- equals() method implementation
- Processing heterogeneous collections
- Plugin/extension type checking
- Serialization/deserialization
- Visitor pattern alternatives
Common Mistakes to Avoid
- Casting without instanceof check
- Not using pattern matching (Java 16+)
- Using instanceof when polymorphism fits
- Checking concrete types too often
- Forgetting null returns false
- Using getClass() when instanceof needed