为什么这个instanceof代码工作并且不会导致编译时错误?

use*_*526 6 java instanceof

在下面的代码中,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 {}
Run Code Online (Sandbox Code Playgroud)

wkl*_*wkl 13

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

您是否认为它会导致编译时错误,因为您认为编译器不知道x类型?

编辑

正如Kirk Woll所评论的那样(感谢Kirk Woll!),如果你正在检查是否xinstanceof一个具体的类,并且编译器可以确定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
   }
}
Run Code Online (Sandbox Code Playgroud)

  • @ user439526啊,这就是你的意思.好点子.您没有看到示例问题的原因是因为您在*interfaces*上使用`instanceof`而在*classes*上没有.编译器永远不会知道给定类型*是否不实现接口,因为潜在的子类可以实现它.正如您所指出的,这与类不同,如果您的示例使用了两个不兼容的类而不是接口,那么您确实会遇到编译器错误. (9认同)