For the below code,
package java_instanceof;
/*
*
* Object I0
* I1 I2 ^ \ . ^
* . . | \ . |
* . . | \ ______ . |
* . . C1 |__B___| I3
* . . / .
* .. / .
* C2 .
* ^ .
* | .
* | .
* | .
* C3
*
*/
interface I0{}; interface I1{}; interface I2 {};
interface I3 extends I0{};
class C1{}; class B implements I0{};
class C2 extends C1 implements I1, I2 {}
class C3 extends C2 implements I3 {}
public class Example {
public static void main(String[] args) {
Object o; Object[] oa;
I0 i0; I0[] i0a;
I1 i1; I1[] i1a;
I2 i2; I2[] i2a;
I3 i3; I3[] i3a;
C1 c1; C1[] c1a;
C2 c2; C2[] c2a;
C3 c3; C3[] c3a;
B b; B[] ba;
//Compile time check
boolean value1 = c3 instanceof B; //compile time check error
boolean value2 = b instanceof C3; // compile time check error
}
}
As a beginner, I would like to know, How is javac
able to raise compile time error Incompatible conditional operand type
? Is the complete class hierarchy known at compile time?
Yes and no. Of course the class hierarchy of all classes and interfaces in the compiled file and in files imported by it are known at compile time. However, at run-time there could be additional classes and interfaces.
In your case however, both C3
and B
are classes, and then the available information is enough to determine that c3
can never refer to an instance of B
, and b
can never refer to an instance of C3
. This is the case because classes inherit from a single (or, in the case of Object
, no) superclass.
With interfaces the situation is different. The following fragment will not lead to a compile time error:
I1 i1 = ... ;
boolean v = i1 instanceof B;
because someone might declare a subclass of B
which also implements I1
.