我最近遇到了以下代码片段的奇怪编译错误:
class A {
}
class B extends A {
}
class Example {
}
class Demo {
public static void main (String args[]){
B b = new B();
if(b instanceof Example) {
System.out.println("Yes it is");
}
}
}
现在我的谓词出现编译错误,表明B
和Example
是不兼容的操作数。我搜索了一会儿,发现如果没有导入右手操作数,Eclipse环境会显示这样的错误。但在我的情况下,所有类都在同一个文件中。所以我无法弄清楚这个问题。是instanceof
仅适用于层次结构以及我尝试过无效的示例吗?
答案 0 :(得分:4)
b
被定义为B,它永远不会是Example
,因为两者之间没有继承关系。你宁愿这样做:
class Demo {
public static void main (String args[]){
A a = new B();
if(a instanceof B) {
System.out.println("Yes it is");
}
}
}
或者如果你坚持一个可以举行例子的类型,那就是:
class Demo {
public static void main (String args[]){
Object o = new Example();
if(o instanceof Example) {
System.out.println("Yes it is");
}
}
}
编译器可以而且必须检查,如果类型可以是给定的实例,请参阅JLS 15.20.2
如果将RelationalExpression转换为ReferenceType将被拒绝作为 编译时错误,然后关系表达式的instanceof同样产生一个 编译时错误。在这种情况下,instanceof表达式的结果 永远不会是真的。
答案 1 :(得分:2)
b
引用的对象绝对不能成为Example
的实例。这在编译时是已知的。
此层次结构中存在B
类型的引用
class B extends A {
}
而Example
位于
class Example {}
类型B
的变量无法引用Example
类型的对象。例如,类型B
的实例显然不是Example
的子类型。此外,B
的任何子类型都是B
的子类。由于Java不支持多重继承,因此它也不能是Example
的子类型。 (如果Example
是interface
,则无法说同样的内容。)
答案 2 :(得分:1)
instanceof
运算符用于运行时类型检查。例如,检查类型A
的引用是否实际包含B
实例是有意义的。但是,Example
和B
是完全不相交的类型 - 对B
的引用可以从不持有Example
类型的实例,因此检查它是毫无意义,在编译时可能会失败。
答案 3 :(得分:1)
instanceof 是仅限运算符继承和实现的工作。如果您正在检查的对象不是来自继承层次结构,那么您将收到编译错误。以下是代码
class Demo {
public static void main (String args[]){
A obj = new B();
if(obj instanceof B) {
System.out.println("Yes it is");
}
}
}
在这里,您无法检查obj instanceof Example
,它的错误不是来自层次结构。