instanceof operator - why there is Illegal compile time error

前提是你 提交于 2019-11-30 23:38:18

The error from Java 8 is:

error: incompatible types: C cannot be converted to D

And indeed, C and D are not in the same lineage (other than both being Object). Since the compiler can tell you at compilation time that the instanceof will never be true, it does. The earlier a problem is caught, the better; the compiler is preventing your having code that is unnecessary or a condition that will never be satisfied. It's like the error you get when you have code that can never be reached because the logic is unambiguous and never allows execution of the code (error: unreachable statement).

Here's a complete example:

public class Example {

    interface I { }
    static class A { int x = 1;}
    static class B extends A implements I { int y = 2;}
    static class C extends B { }
    static class D extends B{ }
    static class E implements I { }

    public static final void main(String[] args) {
        C c2 = new C();
        System.out.println(c2 instanceof D);
    }
}

Which fails with:

Example.java:12: error: incompatible types: C cannot be converted to D
        System.out.println(c2 instanceof D);

But, if you make it so the compiler can't know for sure that the instanceof will always be false, then it does indeed compile and you get false at runtime:

public class Example {

    interface I { }
    static class A { int x = 1;}
    static class B extends A implements I { int y = 2;}
    static class C extends B { }
    static class D extends B{ }
    static class E implements I { }

    public static final void main(String[] args) {
        C c2 = new C();
        doTheCheck(c2);
    }

    static void doTheCheck(Object o) {
        System.out.println(o instanceof D);
    }
}

Since what we're checking, o, could be anything, the compiler doesn't alert you to the invariant check, the code compiles, and you get false as output.

Because compiler knows that casting c2 to type D will always doing to fail at runtime, and hence is marked as compile time error. So it doesn't allow such instanceof to pass through.

Quoting JLS §15.20.2:

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.

Thats because compiler can check at compile time that such instanceof would always return false, you can read on it in JLS:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.20.2

If a cast 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.

RelationalExpression is first operand, and ReferenceType is second: RelationalExpression instanceof ReferenceType

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!