为什么在 instanceOf 之后进行转换?

新手上路,请多包涵

在下面的例子中(来自我的课程包),我们想给 Square 实例 c1 一些其他对象的引用 p1 2,但前提是那些是兼容的类型。

 if (p1 instanceof Square) {c1 = (Square) p1;}

我在这里不明白的是,我们首先检查 p1 确实是一个 Square ,然后我们仍然投它。如果它是 Square ,为什么投?

我怀疑答案在于明显类型和实际类型之间的区别,但我还是很困惑……

编辑:

编译器将如何处理:

 if (p1 instanceof Square) {c1 = p1;}

编辑2:

问题是 instanceof 检查 实际 类型而不是 表面 类型?然后演员表改变了 明显 的类型?

原文由 JDelage 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 544
2 个回答

请记住,您始终可以将 Square 的实例分配给继承链上层的类型。然后,您可能希望将不太具体的类型转换为更具体的类型,在这种情况下,您需要确保您的转换是有效的:

 Object p1 = new Square();
Square c1;

if(p1 instanceof Square)
    c1 = (Square) p1;

原文由 Justin Niessner 发布,翻译遵循 CC BY-SA 3.0 许可协议

旧代码将无法正常工作

隐含的转换功能 毕竟是合理的,但由于向后兼容性,我们很难将此 FR 实现到 java。

看到这个:

 public class A {
    public static void draw(Square s){...} // with implied cast
    public static void draw(Object o){...} // without implied cast
    public static void main(String[] args) {
        final Object foo = new Square();
        if (foo instanceof Square) {
            draw(foo);
        }
    }
}

当前的 JDK 将编译第二个声明方法的用法。如果我们在 java 中实现这个 FR,它会编译使用第一个方法!

🔴 JDK 14

我们最终在 JDK 14 中实现了这个功能。您可能已经注意到,您可以在 instanceof-linkage 中声明一个新变量。这个新变量已经定义了一个自动向下转换为指定类型的值。

 if (any instanceof String s) {
  System.out.println(s);
}

原文由 Grim 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题