Java instanceof operator

Jakob Jenkov
Last update: 2020-07-04

The Java instanceof operator can determine if a given Java object is an instance of a given class, superclass or interface. This is useful if you have an object of an unknown type and you need to cast it to a known type to use it as intended.

The Java instanceof operator is also referred to as a type comparison operator because it compares the type of a given instance (object) with a specific type (class or interface).

Java instanceof Example

To understand how the Java instanceof operator works, let us look at a simple Java instanceof example:

import java.util.HashMap;
import java.util.Map;

public class InstanceofExample {

    public static void main(String[] args) {
        Map<Object, Object> map = new HashMap();

        boolean mapIsObject = map instanceof Object;

        System.out.println(mapIsObject);
    }
}

Notice the statement:

 boolean mapIsObject = map instanceof Object;

The expression map instanceof Object will evaluate to true if the map variable references an object that is an instance of class Object, or any subclass of class Object. Since all classes in Java inherit from Object, this expression will evaluate to true.

Instanceof With Same Class

As mentioned earlier, the Java instanceof operator will evaluate to true if you compare an object to the exact class of that object. Here is a Java instanceof example showing a comparison of an object to its exact class:

HashMap<Object, Object> map = new HashMap();

boolean mapIsObject = map instanceof HashMap;

The last line of this example will set mapIsObject to true because the map variable references an object of type HashMap.

Note that it is the actual type of the referenced object that is compared against - not the type of the variable referencing the object. Here is another Java instanceof example illustrating that:

Map<Object, Object> map = new HashMap();

boolean mapIsObject = map instanceof HashMap;

Notice that the type of the variable is now Map and not HashMap . Map is not a subclass of HashMap. Thus, a Map is not guaranteed to be an instance of a HashMap. However, since the actual object assigned to the map variable is a HashMap object, the second line of the example will still evaluate to true.

Instanceof With Superclass

As also mentioned earlier, the Java instanceof operator also evaluates to true when comparing an object against a superclass of the type of that object. Here is a Java instanceof example illustrating that:

Map<Object, Object> map = new HashMap();

boolean mapIsObject = map instanceof Object;

Since HashMap is a subclass of Object - even if not a direct subclass, the expression map instanceof Object evaluates to true.

Note, that it does not matter how high up in the inheritance hierarchy the compared type is superclass of the type of the object. As long as the type compared to is a superclass somewhere up the inheritance hierarchy, instanceof will evaluate to true.

Instanceof With Interface

The Java instanceof operator also works when comparing an object against an interface instead of a class. Here is a Java instanceof example showing that:

HashMap<Object, Object> map = new HashMap();

boolean mapIsObject = map instanceof Map;

Notice, that even if the map variable is of type HashMap, the instanceof operator returns true for the expression map instanceof Map because the HashMap class implements the Map interface. This would also be true if the variable was of type Map, as in this example:

Map<Object, Object> map = new HashMap();

boolean mapIsObject = map instanceof Map;

Instanceof With Superinterface

The Java instanceof operator also evaluates to true when comparing an object against a superinterface which the class of the object, or a superclass of the object implements. Here is a Java instanceof example illustrating that:

SortedMap<Object, Object> map = new TreeMap();

boolean mapIsObject = map instanceof Map;

The SortedMap interface extends the Map interface. Map is thus a superinterface of SortedMap. The TreeMap class implements SortedMap, and thus also indirectly the Map interface. Thus, the last line of the example evaluates to true

Instanceof With null

The Java instanceof operator always evaluates to false when a null variable is compared against any class or interface. Here is a Java instanceof example illustrating the comparison of null against a class:

Map<Object, Object> map = null;

boolean mapIsObject = map instanceof Map;

Note, that even if the type of the map variable is Map, and the map variable is compared against the Map interface, the result of the comparison is still false. That is because it is not the reference type that is compared against the target class or interface, but the actual type of the referenced object. Since the map variable has the value null, that is what is compared against the Map interface in the expression map instanceof Map. Since null is not an instance of Map, the expression evaluates to false.

The Java Compiler and the instanceof Operator

Sometimes the Java compiler can detect already at compile time that an instanceof expression will always evaluate to false. Here is a Java instanceof example illustrating that situation:

String myString = "Hey";

if(myString instanceof Integer) {

}

Since a Java String object can never be an instance of the Java Integer class, the Java compiler will catch this an give you an error.

Using instanceof to Downcast

One of the most common uses of the Java instanceof operator is to downcast an object of supertype to a subtype. Here is a Java instanceof example illustrating the downcast use case:

Map<Object, Object> map = new TreeMap;

//... more code that is left out

if(map instanceof SortedMap) {
  SortedMap sortedMap = (SortedMap) map;

  //do something with sortedMap.
}

The downcasting can also be a bit more "generic" as illustrated in this instanceof example:

Object myObject = ... // get object from somewhere

if(myObject instanceof String) {
    String myString = (String) myObject;

} else if(myObject instance of Integer) {
    Integer myInteger = (Integer) myObject;

}

Notice, that the variable referencing the object is of type Object. That means that the actual class of the referenced object could be pretty much any class (since all classes are subclasses of Object).

instanceof With Pattern Matching

In Java 14 the Java instanceof operator has been extended with pattern matching functionality. The functionality is still only in preview in Java 14, but there is a pretty good chance that it will stay in this or some similar form. In short, we can avoid the explicit downcast of an object when comparing it against a subclass. Here is a Java instanceof example illustrating the instanceof pattern matching functionality:

Object myObject = ... // get object from somewhere

if(myObject instanceof String str) {
    System.out.println(str.substring(0,5));
}

Notice the str variable after the String class name in the instanceof expression inside the if-statement. If the myObject variable references an object of type String, the str variable will be bound to that object - cast to a String. Thus, inside the if-statement it is no longer necessary to explicitly cast the myObject variable to a String.

Without the pattern matching instanceof functionality, the example code would have looked like this:

Object myObject = ... // get object from somewhere

if(myObject instanceof String) {
    String str = (String) myObject;
    System.out.println(str.substring(0,5));
}

Notice the explicit cast on the first line inside the if-statement.

If the instanceof expression evaluates to true, you can actually use the downcast variable directly within the same expression. Here is an instanceof example illustrating that:

Object myObject = ... // get object from somewhere

if(myObject instanceof String str &&
   str.startsWith("Hello") ) {

    System.out.println(str + " starts with Hello");
}

Notice how the str variable is used within the same expression that declares it. Since the right hand side of the expression is only evaluated if the left hand side evaluates to true, this cannot result in startsWith() being called on a non-String object.

Jakob Jenkov

Featured Videos

Java ConcurrentMap + ConcurrentHashMap

Java Generics

Java ForkJoinPool

P2P Networks Introduction

















Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Previous
Next tutorial in this tutorial trail
Next