class A {}
class B {}
public class Demo {
public static void main(String[] args) {
A a = new A();
System.out.println(a instanceof B);
}
}
此代码给出编译时错误。当对象不是指定的类的实例时,如何使用instanceof
给出 false 而不是编译时错误。
Java知道A
不能是B
所以它不会编译。如果将行更改为
Object a = new A();
它将编译(并返回 false(,因为它无法再判断是否可以将Object
转换为类型 B
。
如果class A
和B
没有通过继承关联,则编译器将在您尝试执行a instanceof B
时抛出错误
在您的情况下,A
不是B
的子类,因此您不能像a instanceof B
那样进行instanceof
检查
但是,如果您像下面这样更改课程:
class A {}
class B extends A {}
public static void main(String[] args) {
B b=new B();
System.out.println(b instanceof A);
}
现在b instanceof A
将返回true
B
因为 IS-A(类型(A
您可以在此处阅读有关同一主题的 Java 文档:
实例运算符将对象与指定类型进行比较。你 可以使用它来测试对象是否是类的实例,实例 子类或实现特定 接口。
你可以使用这个:
System.out.println(a.getClass().equals(B.class));
而不是:
System.out.println(a instanceof B);
引用JLS Sec 15.20.2
:如果
ReferenceType
RelationalExpression
的强制转换 (§15.16( 将作为编译时错误被拒绝,则instanceof
关系表达式同样会产生编译时错误。在这种情况下,instanceof
表达的结果永远不可能是真的。
(他们描述RelationalExpression instanceof ReferenceType
(
你也不能写B b = (B) a;
,因为A
和B
都是类(*(,并且是不相关的,从某种意义上说,A
不会直接或间接地扩展到B
,反之亦然。
因此,对A
的引用永远不能包含B
的实例,所以测试它是荒谬的。因此,编译器会阻止您对此进行测试,因为它可能指示逻辑错误。
(*( 如果B
是一个接口,你可以写a instanceof B
,因为a
可能引用一个A
子类,它另外实现了B
,例如
class ChildOfA extends A implements B {}
A a = new ChildOfA();
System.out.println(a instanceof B); // fine.