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

发布于 2024-09-26 22:52:00 字数 373 浏览 5 评论 0原文

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

In the following code, the type of x is I (although x also implements J but thats not known at compile time) so why is it that the code at (1) doesn't result in a compile time error.
Because at compile time only the type of the reference is considered.

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 {}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

耳钉梦 2024-10-03 22:52:00

instanceof 用于运行时确定对象类型。您试图在程序运行时确定 x 是否确实是 J 类型的对象,以便编译。

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

编辑

正如 Kirk Woll 评论的那样(感谢 Kirk Woll!),如果您检查 x 是否是具体类的 instance ,并且编译器可以确定x的类型,那么你会在编译时得到一个错误。

来自 Java 语言规范:

如果 RelationalExpression 到 ReferenceType 的强制转换会被视为编译时错误而被拒绝,则关系表达式的 instanceof 同样会产生编译时错误。在这种情况下,instanceof 表达式的结果永远不可能为 true。

举个例子:

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
   }
}

instanceof is used used for runtime determination of an object's type. You are trying to determine if x is really an object of type J when the program is running, so it compiles.

Were you thinking it should result in a compile-time error because you think the compiler does not know x's type?

Edit

As Kirk Woll has commented (thanks Kirk Woll!), if you were checking if x is an instanceof a concrete class, and the compiler can determine x's type, then you will get an error at compile time.

From the Java Language Specification:

If a cast of the RelationalExpression to the ReferenceType would be rejected as a compile-time error, then the instanceof relational expression likewise produces a compile-time error. In such a situation, the result of the instanceof expression could never be true.

As an example of this:

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
   }
}
一城柳絮吹成雪 2024-10-03 22:52:00

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

instanceof is a run-time operator, not compile-time, so it's being evaluated using the actual type of the object being referenced.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文