简体   繁体   中英

compile time check using instanceof

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 .

Yes ! off course, The hierarchy, may it be "implements" or "extends" etc is known at the compile time.

Without these checks, you cannot take advantage of OOPS even while programming further into the tree of relations that you are trying to code.

Consider an example of Object Class itself, if Object was not the parent of all class, you might not have been able to Override the toString(), hashcode(), clone() methods that basically come from Object Class. So you get these methods in intellisence of any IDE, hence these are already pre-compiled before even execution.

Yes, The Compiler first looks in the method's lexical hierarchy, then in the class hierarchy, and finally, in the global scope. for more related information on how compiler works you can refer Book "Engineering a Compiler" by Keith Cooper- Method and class Invocation topic.

for your first question you may find this http://codereply.com/answer/42s61x/instanceof-incompatible-conditional-operand-types.html helpful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM