6

在下面的代码中,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 {}
4

2 回答 2

13

instanceof用于在运行时确定对象的类型。您正在尝试确定程序运行时x是否真的是一个类型的对象,因此它会编译。J

您是否认为它应该导致编译时错误,因为您认为编译器不知道x's 的类型?

编辑

正如 Kirk Woll 所评论的(感谢 Kirk Woll!),如果您正在检查是否xinstanceof一个具体的类,并且编译器可以确定x的类型,那么您将在编译时收到错误消息。

来自 Java 语言规范:

如果将 RelationalExpression 转换为 ReferenceType 将作为编译时错误被拒绝,则 instanceof 关系表达式同样会产生编译时错误。在这种情况下,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
   }
}
于 2010-10-09T19:10:58.307 回答
2

instanceof 是运行时运算符,而不是编译时运算符,因此使用被引用对象的实际类型对其进行评估。

于 2010-10-09T19:11:09.760 回答