172

What is the instanceof operator used for? I've seen stuff like

if (source instanceof Button) {
    //...
} else {
    //...
}

But none of it made sense to me. I've done my research, but came up only with examples without any explanations.

Pacerier
  • 86,231
  • 106
  • 366
  • 634
Ben
  • 1,745
  • 2
  • 11
  • 3
  • 43
    There is nothing wrong with asking questions here, but if you are learning Java you might want to get a book. Any decent Java book would have the answer to this question and the next 1000 you're going to have. – President James K. Polk Sep 05 '11 at 23:32
  • Such an operator has many specific uses. This would be a specific question if it asked for an explanation of one of the examples that did not make sense to you. – Raedwald Aug 23 '13 at 07:15
  • 3
    The answers below are correct, however note that instanceof is an overused operator 9 times out of 10 it can be replaced by a proper use of polymorphism (not always, but often) – Richard Tingle Aug 24 '13 at 18:22
  • I'd go one further than Richard: I have NEVER seen a valid use of instanceof. It's only useful for quick hacks on top of poorly designed code. If you don't like OOP, write in another language (there are plenty). Just say, "no" to instanceof! – SMBiggs Nov 27 '15 at 22:14
  • 5
    @ScottBiggs Is there a good alternative to `instanceof` when overriding `equals`? – Ben Aaronson Sep 07 '16 at 14:55
  • @BenAaronson I feel that Scott and Richard are taking a specific rule from religious scripture and applying it too broadly to everyday life. :) Instanceof should only be used when you are *forced* to work with objects of unknown type. If you have to use instanceof with known types, *then* it is a sign of bad design. As usual, religious texts conveniently forget that sometimes life forces us to use bad code written by bad people and there's absolutely nothing we can do about it (other than use instanceof). Thus, instanceof is just fine within equals method. – Torben Aug 08 '18 at 12:44
  • While there are several answers that are syntactically correct about _how_ it can be used. They are poor choices compared to polymorphism. It is like goto, there are plenty of valid cases were it can be used, but in most cases there are objectively better ways to do it. – Martin Spamer Feb 06 '20 at 13:46

18 Answers18

234

instanceof keyword is a binary operator used to test if an object (instance) is a subtype of a given Type.

Imagine:

interface Domestic {}
class Animal {}
class Dog extends Animal implements Domestic {}
class Cat extends Animal implements Domestic {}

Imagine a dog object, created with Object dog = new Dog(), then:

dog instanceof Domestic // true - Dog implements Domestic
dog instanceof Animal   // true - Dog extends Animal
dog instanceof Dog      // true - Dog is Dog
dog instanceof Object   // true - Object is the parent type of all objects

However, with Object animal = new Animal();,

animal instanceof Dog // false

because Animal is a supertype of Dog and possibly less "refined".

And,

dog instanceof Cat // does not even compile!

This is because Dog is neither a subtype nor a supertype of Cat, and it also does not implement it.

Note that the variable used for dog above is of type Object. This is to show instanceof is a runtime operation and brings us to a/the use case: to react differently based upon an objects type at runtime.

Things to note: expressionThatIsNull instanceof T is false for all Types T.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
  • 16
    I just tried - `Object dog = new Dog(); System.out.println(dog instanceof Cat);`. This compiles just fine and prints `false`. The compiler is not allowed to determine at compile time that `dog` cannot be a Cat (per the rules in the JLS) – Erwin Bolwidt Oct 03 '16 at 13:15
  • @ErwinBolwidt You made a mistake when you tried that. For anyone wondering: JLS Section 15.20.2 is the one you are looking for. For a minimal nonworking example: `boolean b = "foo" instanceof Integer;` – Felix S Aug 07 '17 at 08:04
  • 4
    @FelixS You need to read the answer again. The answer is about `Object indirect = ...; if (indirect instanceof Something)`. It's not about `if (literal instanceof Something)` like you seem to be assuming. – Erwin Bolwidt Aug 07 '17 at 09:32
  • 2
    @ErwinBolwidt Oh, right, I must have skipped over the `Object dog` part. My bad! – Felix S Aug 08 '17 at 10:21
  • `dog instanceof Cat // does not even compile!`(because it is a class). If `Cat` were an interface then it would compile. – Hamza Belmellouki Jun 13 '19 at 15:38
44

It's an operator that returns true if the left side of the expression is an instance of the class name on the right side.

Think about it this way. Say all the houses on your block were built from the same blueprints. Ten houses (objects), one set of blueprints (class definition).

instanceof is a useful tool when you've got a collection of objects and you're not sure what they are. Let's say you've got a collection of controls on a form. You want to read the checked state of whatever checkboxes are there, but you can't ask a plain old object for its checked state. Instead, you'd see if each object is a checkbox, and if it is, cast it to a checkbox and check its properties.

if (obj instanceof Checkbox)
{
    Checkbox cb = (Checkbox)obj;
    boolean state = cb.getState();
}
Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
30

As described on this site:

The instanceof operator can be used to test if an object is of a specific type...

if (objectReference instanceof type)

A quick example:

String s = "Hello World!"
return s instanceof String;
//result --> true

However, applying instanceof on a null reference variable/expression returns false.

String s = null;
return s instanceof String;
//result --> false

Since a subclass is a 'type' of its superclass, you can use the instanceof to verify this...

class Parent {
    public Parent() {}
}

class Child extends Parent {
    public Child() {
        super();
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        System.out.println( child instanceof Parent );
    }
}
//result --> true

I hope this helps!

Shantaram Tupe
  • 1,646
  • 3
  • 16
  • 42
fireshadow52
  • 6,298
  • 2
  • 30
  • 46
15

This operator allows you to determine the type of an object. It returns a boolean value.

For example

package test;

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

public class instanceoftest
{
    public static void main(String args[])
    {
        Map m=new HashMap();
        System.out.println("Returns a boolean value "+(m instanceof Map));
        System.out.println("Returns a boolean value "+(m instanceof HashMap));
        System.out.println("Returns a boolean value "+(m instanceof Object));
        System.out.println("Returns a boolean value "+(m instanceof Date));
    }
} 

the output is:

Returns a boolean value true
Returns a boolean value true
Returns a boolean value true
Returns a boolean value false
River
  • 8,585
  • 14
  • 54
  • 67
Purendra Agrawal
  • 558
  • 1
  • 6
  • 17
14

If source is an object variable, instanceof is a way of checking to see if it is a Button or not.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
5

As mentioned in other answers, the canonical typical usage of instanceof is for checking if an identifier is referring to a more specific type. Example:

Object someobject = ... some code which gets something that might be a button ...
if (someobject instanceof Button) {
    // then if someobject is in fact a button this block gets executed
} else {
    // otherwise execute this block
}

Note however, that the type of the left-hand expression must be a parent type of the right hand expression (see JLS 15.20.2 and Java Puzzlers, #50, pp114). For example, the following will fail to compile:

public class Test {
    public static void main(String [] args) {
        System.out.println(new Test() instanceof String); // will fail to compile
    }
}

This fails to compile with the message:

Test.java:6: error: inconvertible types
        System.out.println(t instanceof String);
                       ^
  required: String
  found:    Test
1 error

As Test is not a parent class of String. OTOH, this compiles perfectly and prints false as expected:

public class Test {
    public static void main(String [] args) {
        Object t = new Test();
        // compiles fine since Object is a parent class to String
        System.out.println(t instanceof String); 
    }
}
Adam Parkin
  • 17,891
  • 17
  • 66
  • 87
1
public class Animal{ float age; }

public class Lion extends Animal { int claws;}

public class Jungle {
    public static void main(String args[]) {

        Animal animal = new Animal(); 
        Animal animal2 = new Lion(); 
        Lion lion = new Lion(); 
        Animal animal3 = new Animal(); 
        Lion lion2 = new Animal();   //won't compile (can't reference super class object with sub class reference variable) 

        if(animal instanceof Lion)  //false

        if(animal2 instanceof Lion)  //true

        if(lion insanceof Lion) //true

        if(animal3 instanceof Animal) //true 

    }
}
Walery Strauch
  • 6,792
  • 8
  • 50
  • 57
mcfred
  • 1,183
  • 2
  • 29
  • 68
1

Most people have correctly explained the "What" of this question but no one explained "How" correctly.

So here's a simple illustration:

String s = new String("Hello");
if (s instanceof String) System.out.println("s is instance of String"); // True
if (s instanceof Object) System.out.println("s is instance of Object"); // True
//if (s instanceof StringBuffer) System.out.println("s is instance of StringBuffer"); // Compile error
Object o = (Object)s;
if (o instanceof StringBuffer) System.out.println("o is instance of StringBuffer"); //No error, returns False
else System.out.println("Not an instance of StringBuffer"); // 
if (o instanceof String) System.out.println("o is instance of String"); //True

Outputs:

s is instance of String
s is instance of Object
Not an instance of StringBuffer
o is instance of String

The reason for compiler error when comparing s with StringBuffer is well explained in docs:

You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.

which implies the LHS must either be an instance of RHS or of a Class that either implements RHS or extends RHS.

How to use use instanceof then?
Since every Class extends Object, type-casting LHS to object will always work in your favour:

String s = new String("Hello");
if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //No compiler error now :)
else System.out.println("Not an instance of StringBuffer");

Outputs:

Not an instance of StringBuffer
sziraqui
  • 5,763
  • 3
  • 28
  • 37
  • In the last example, why is it returning "Not an instance of StringBuffer"? Since you typecasted s to Object on LHS and checking if it is an instanceof RHS, `if ((Object)s instanceof StringBuffer) System.out.println("Instance of StringBuffer"); //shouldn't this be true`, since we are typecasting s to Object? – sofs1 Sep 12 '18 at 05:17
  • Because s is a reference to String object (Java employs dynamic polymorphism unlike C++) and String isn't a subclass of StringBuffer. – sziraqui Sep 13 '18 at 10:18
  • I think you've missed the explanation of why `s instanceof StringBuffer`. You've re-iterated the criteria for it being true. An `Object` is not necessarily an instance of the RHS or a class that implents or Extends the RHS. It *can* be though. A String will never be an instance of a StringBuffer. – matt Jun 15 '22 at 20:43
1

Best explanation is jls. Always try to check what source says. There you will get the best answer plus much more. Reproducing some parts here:

The type of the RelationalExpression operand of the instanceof operator must be a reference type or the null type; otherwise, a compile-time error occurs.

It is a compile-time error if the ReferenceType mentioned after the instanceof operator does not denote a reference type that is reifiable (§4.7).

If a cast (§15.16) of the RelationalExpression to the ReferenceType would be rejected as a compile-time error, then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.

nanosoft
  • 2,913
  • 4
  • 41
  • 61
0

Instance of keyword is helpful when you want to know particular object's instance .

Suppose you are throw exception and when you have catch then perform sum custom operation and then again continue as per your logic (throws or log etc)

Example : 1) User created custom exception "InvalidExtensionsException" and throw it as per logic

2) Now in catch block catch (Exception e) { perform sum logic if exception type is "InvalidExtensionsException"

InvalidExtensionsException InvalidException =(InvalidExtensionsException)e;

3) If you are not checking instance of and exception type is Null pointer exception your code will break.

So your logic should be inside of instance of if (e instanceof InvalidExtensionsException){ InvalidExtensionsException InvalidException =(InvalidExtensionsException)e; }

Above example is wrong coding practice However this example is help you to understand use of instance of it.

vaquar khan
  • 10,864
  • 5
  • 72
  • 96
0

Can be used as a shorthand in equality check.

So this code

if(ob != null && this.getClass() == ob.getClass) {
}

can be written as

if(ob instanceOf ClassA) {
}
 
Wolfson
  • 1,187
  • 17
  • 22
mirmdasif
  • 6,014
  • 2
  • 22
  • 28
  • This is nonsense. `"foo" instanceof Object` but `"foo".getClass() != new Object().getClass()`. In other words, class comparison reports a match only if both object are instances of exactly the same class while `instanceof` also reports a match if the LHS is a descendant of the RHS or the LHS implements the RHS. – DarthGizka Jul 18 '23 at 06:42
0

The java instanceof operator is used to test whether the object is an instance of the specified type (class or subclass or interface).

The instanceof in java is also known as type comparison operator as it compares the instance with type. It returns either true or false. If we apply the instanceof operator with any variable that has null value, it returns false.

From JDK 14+ which includes JEP 305 we can also do "Pattern Matching" for instanceof

Patterns basically test that a value has a certain type, and can extract information from the value when it has the matching type. Pattern matching allows a more clear and efficient expression of common logic in a system, namely the conditional removal of components from objects.

Before Java 14

if (obj instanceof String) {
    String str = (String) obj; // need to declare and cast again the object
    .. str.contains(..) ..
}else{
     str = ....
}

Java 14 enhancements

if (!(obj instanceof String str)) {
    .. str.contains(..) .. // no need to declare str object again with casting
} else {
    .. str....
}

We can also combine the type check and other conditions together

if (obj instanceof String str && str.length() > 4) {.. str.contains(..) ..}

The use of pattern matching in instanceof should reduce the overall number of explicit casts in Java programs.

PS: instanceOf will only match when the object is not null, then only it can be assigned to str.

Player_Neo
  • 1,413
  • 2
  • 19
  • 28
0

instanceof operator can also be used when the type of the elements present in the object(listObj) is unknown at run time. In those cases instanceof operator can be used to figure out the elements type and will be helpful to proceed further based on the requirement.

For Example :

   String str = "";
   int a = 0;
   Integer b = null;

    List listObj = new ArrayList<>();
    listObj.add("String");
    listObj.add(100);
    listObj.add(10.5);
    listObj.add(1l);
    
    if (listObj.get(0) instanceof String) {
        System.out.println("String");
        str = (String)listObj.get(0);
    }
    
    if (listObj.get(1) instanceof Integer) {
        System.out.println("Integer");
         a = (int)listObj.get(1);
         b = (Integer)listObj.get(1);
    }
    
    if (listObj.get(2) instanceof Double) {
        System.out.println("Double");
    }
    
    if (listObj.get(3) instanceof Long) {
        System.out.println("Long");
    }

if the value retrieved from the object is assigned to a variable,JVM will ask you to cast it to a particular type at compile time.

lets consider :

int x = (String)listObj.get(0); 

// In above example , element retrieved from listObj is String and is casted to int. This will resolve the compile time errors.But at the time of execution JVM will throw ClassCastException.

so instead of randomly assigning values to a variable that does not matches the type, we can use instanceof operator to check and assign the values to the correct variables to avoid errors.

Akash R
  • 129
  • 7
0

The instanceof operator compares an object to a specified type. You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.

http://download.oracle.com/javase/tutorial/java/nutsandbolts/op2.html

Ben
  • 13,297
  • 4
  • 47
  • 68
-1
class Test48{
public static void main (String args[]){
Object Obj=new Hello();
//Hello obj=new Hello;
System.out.println(Obj instanceof String);
System.out.println(Obj instanceof Hello);
System.out.println(Obj instanceof Object);
Hello h=null;
System.out.println(h instanceof Hello);
System.out.println(h instanceof Object);
}
}  
-2

You could use Map to make higher abstraction on instance of

private final Map<Class, Consumer<String>> actions = new HashMap<>();

Then having such map add some action to it:

actions.put(String.class, new Consumer<String>() {
        @Override
        public void accept(String s) {
           System.out.println("action for String");       
        }
    };

Then having an Object of not known type you could get specific action from that map:

actions.get(someObject).accept(someObject)
tomekl007
  • 47
  • 2
-2

The instanceof operator is used to check whether the object is an instance of the specified type. (class or subclass or interface).

The instanceof is also known as type comparison operator because it compares the instance with type. It returns either true or false.

class Simple1 {  
public static void main(String args[]) {  
Simple1 s=new Simple1();  
System.out.println(s instanceof Simple1); //true  
}  
}  

If we apply the instanceof operator with any variable that has null value, it returns false.

Viraj Pai
  • 61
  • 4
-2

Very simple code example:

If (object1 instanceof Class1) {
   // do something
} else if (object1 instanceof Class2) {
   // do something different
}

Be careful here. In the example above, if Class1 is Object, the first comparison will always be true. So, just like with exceptions, hierarchical order matters!

mjuarez
  • 16,372
  • 11
  • 56
  • 73