考虑以下代码,我不明白为什么"System.out.println( c2 instanceof D);"
将导致“非法编译时错误”但不返回“false”?非常感谢您的帮助!
interface I { }
class A { int x = 1;}
class B extends A implements I { int y = 2;}
class C extends B { }
class D extends B{ }
class E implements I { }
C c2 = new C();`
答案 0 :(得分:2)
因为编译器知道对类型c2
进行转换D
总是在运行时失败,因此被标记为编译时错误。所以它不允许这样的instanceof
通过。
如果RelationalExpression对ReferenceType的强制转换(第15.16节)将作为编译时错误被拒绝,则关系表达式的实例同样会产生编译时错误。在这种情况下,instanceof表达式的结果永远不会成立。
答案 1 :(得分:1)
Java 8的错误是:
error: incompatible types: C cannot be converted to D
事实上,C
和D
不在同一个血统中(除了Object
之外)。由于编译器可以在编译时告诉你instanceof
永远不会成立,它确实如此。问题越早发现越好;编译器阻止您拥有不必要的代码或永远不会满足的条件。这就像你得到的代码永远无法达到的错误,因为逻辑是明确的,并且从不允许执行代码(error: unreachable statement
)。
这是一个完整的例子:
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);
}
}
哪个失败了:
Example.java:12: error: incompatible types: C cannot be converted to D System.out.println(c2 instanceof D);
但是,如果您这样做,编译器无法确定instanceof
将始终为false,那么它确实编译并且您在运行时得到false
:
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);
}
}
由于我们正在检查的内容o
可能是什么,编译器不会提醒您进行不变检查,代码编译,并且您获得false
作为输出
答案 2 :(得分:0)
这是因为编译器可以在编译时检查这样的instanceof
总是返回false,你可以在JLS中读取它:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.20.2
如果将RelationalExpression转换为ReferenceType 作为编译时错误被拒绝,然后是关系实例 表达式同样会产生编译时错误。在这样的 情况,表达式instanceof的结果永远不会 真。
RelationalExpression是第一个操作数,ReferenceType是第二个:RelationalExpression instanceof ReferenceType