What is the instanceof
operator used for? I\'ve seen stuff like
if (source instanceof Button) {
//...
} else {
//...
}
If source
is an object
variable, instanceof
is a way of checking to see if it is a Button
or not.
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);
}
}
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
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.
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)