gpt4 book ai didi

java - 为什么 javac 允许一些不可能的强制转换而不是其他强制转换?

转载 作者:行者123 更新时间:2023-12-01 06:31:19 24 4
gpt4 key购买 nike

如果我尝试使用 Stringjava.util.Date ,Java 编译器捕获错误。那么为什么编译器不将以下内容标记为错误呢?

List<String> strList = new ArrayList<>();                                                                      
Date d = (Date) strList;

当然,JVM 会抛出 ClassCastException在运行时,但编译器不会标记它。

行为与 javac 1.8.0_212 和 11.0.2 相同。

最佳答案

Actor 阵容在技术上是可行的。 javac 无法轻易证明您的情况并非如此,而 JLS 实际上将其定义为有效的 Java 程序,因此标记错误是不正确的。

这是因为 List是一个接口(interface)。所以你可以有一个 Date 的子类实际实现 List伪装成 List在这里 - 然后将其转换为 Date会很好的。例如:

public class SneakyListDate extends Date implements List<Foo> {
...
}

进而:
List<Foo> list = new SneakyListDate();
Date date = (Date) list; // This one is valid, compiles and runs just fine

检测这样的场景可能并不总是可能的,因为如果实例来自例如一个方法,则它需要运行时信息。即使这样,编译器也需要付出更多的努力。由于类树根本无法匹配,编译器只会阻止绝对不可能的强制转换。正如所见,这里不是这种情况。

请注意,JLS 要求您的代码是有效的 Java 程序。在 5.1.6.1. Allowed Narrowing Reference Conversion它说:

A narrowing reference conversion exists from reference type S to reference type T if all of the following are true:

  • [...]
  • One of the following cases applies:
    • [...]
    • S is an interface type, T is a class type, and T does not name a final class.


因此,即使编译器可以确定您的情况实际上是不可能的,也不允许标记错误,因为 JLS 将其定义为有效的 Java 程序。

它只允许显示警告。

关于java - 为什么 javac 允许一些不可能的强制转换而不是其他强制转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60794343/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com