在下面的代码中,x的类型是I(尽管x也实现了J但在编译时不知道),为什么(1)处的代码不会导致编译时错误。 因为在编译时只考虑引用的类型。
public class MyClass {
public static void main(String[] args) {
I x = new D();
if (x instanceof J) //(1)
System.out.println("J");
}
}
interface I {}
interface J {}
class C implements I {}
class D extends C implements J {}
答案 0 :(得分:13)
instanceof
用于运行时确定对象的类型。您正在尝试在程序运行时确定x
是否真的是J
类型的对象,因此它会进行编译。
您是否认为它会导致编译时错误,因为您认为编译器不知道x
的类型?
修改强>
正如Kirk Woll所评论的那样(感谢Kirk Woll!),如果您正在检查x
是否是instanceof
具体类,并且编译器可以确定x
的类型,然后你会在编译时遇到错误。
来自Java语言规范:
如果将RelationalExpression转换为ReferenceType将作为编译时错误被拒绝,则关系表达式的实例同样会产生编译时错误。在这种情况下,instanceof表达式的结果永远不会成立。
作为一个例子:
import java.io.Serializable;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
class SerializableClass implements Serializable
{
private writeObject(ObjectOutputStream out) {}
private readObject(ObjectInputStream in) {}
}
public class DerivedSerializableClass extends SerializableClass
{
public static void main(String[] args)
{
DerivedSerializableClass dsc = new DerivedSerializableClass();
if (dsc instanceof DerivedSerializableClass) {} // fine
if (dsc instanceof Serializable) {} // fine because check is done at runtime
if (dsc instanceof String) {} // error because compiler knows dsc has no derivation from String in the hierarchy
Object o = (Object)dsc;
if (o instanceof DerivedSerializableClass) {} // fine because you made it Object, so runtime determination is necessary
}
}
答案 1 :(得分:2)
instanceof是一个运行时运算符,而不是编译时,所以它是使用被引用对象的实际类型进行计算的。