Engineering Full Stack Apps with Java and JavaScript
The instanceof operator compares an object to a given type and checks if the type of object in left side is assignment-compatible to the type in the right side. i.e., if we can say right-side-type = left-side-type object without any casting.
In Java, you can assign a child to a parent (or grand parent). So we can exlpain instanceof in simpler terms as, instanceof operator compares an object reference (left side) to a type (right side) and see if the type of the actual object in the reference in left side is a child (or sub child) of the type in right side.
package inheritance; interface I { } class A implements I { } class B extends A { } class C extends B { } public class InstanceOfCheck { public static void main(String[] args) { A a = new A(); B b = new B(); C c = new C(); A ac = new C(); // C cc = ac is not possible, // but ac Instance of C will return true. System.out.println(a instanceof A); System.out.println(a instanceof I); System.out.println(b instanceof B); System.out.println(b instanceof A); System.out.println(b instanceof I); System.out.println(c instanceof C); System.out.println(c instanceof B); System.out.println(c instanceof A); System.out.println(c instanceof I); System.out.println(ac instanceof C); } }
Here, all the print statements will return true.
You cannot compare two incompatible types, which does not have any possibility of becoming compatible.
You will get a compiler error with text as "Incompatible conditional operand types..." if compiler does not see any possibility of getting a true.
For instance, if A and B are two unrelated classes, and if we compare an object of A with instanceof to B, then compiler will give an error: Incompatible conditional operand types A and B.
If B is an unrelated interface to A, then there is a possibility that a child of A can also implement B and get assigned to a reference of A.
However in this case, B was a class, a child of A (which has already extended from A), will not be able to extend one more class.
Also, if we make the class A as final, then even if B is an interface, compiler will not allow to compile as A cannot be subclassed and there is no more probability of one of A's child implementing the interface.
The null is not an instance of anything. So if we compare null to any type it will return false.
package inheritance; interface I2 { } class A2 implements I2 { } class B2 extends A2 { } class C2 { } public class InstanceofCheck2 { public static void main(String[] args) { I2 i = new B2(); A2 a = new A2(); B2 b = new B2(); C2 c = new C2(); // Below line will compile as A2 and B2 are related, // But will return false as A2 is not a child of B2. System.out.println(a instanceof B2); //line 1 // Below line will not compile as // C2 and A2 are not compatible System.out.println(c instanceof A2); //line 2 // Below line will compile. // C2 and I2 are not related now, // But a child of C2 (which could be held in c) // Could implement I2 in future. System.out.println(c instanceof I2); //line 3 } }
If we add final to class C2, then line 3 compilation will fail, as C2 cannot be subclassed and hence there is no possibility of a relationship through C2's child implementing I2.
The class java.lang.Class has a method instance, that does the same.
For any non-null reference obj, the expression (obj instanceof Object) will always yield true.
Note that instanceof operator does not accept objects as the right hand side operand.
Just draw the inheritance hierarchy diagram from the question, with a directed line from children to all its parents (draw only lines to immediate parents). If there is a direct or indirect path from the type of actual object on the left side to the type on the right side, then instance of will return true.
Comments
Nice Post
Nice explanation....... :)