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 swimming

equals() 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