【问题标题】:Casting Nested Generic Types铸造嵌套的泛型类型
【发布时间】:2021-02-04 00:58:24
【问题描述】:

我知道在 Java 中将List<Number> 转换为List<Double> 是非法的,因为List<Double> 不是List<Number> 的子类型:

    List<Number> list1 = new ArrayList<>();
    List<Double> list2 = (List<Double>) list1;  // inconvertible types

基于这种理解,我认为将List&lt;? extends List&lt;Number&gt;&gt; 转换为List&lt;List&lt;Double&gt;&gt; 也是非法的,因为我认为List&lt;Double&gt; 不属于List&lt;Number&gt; 给出的类型家族。然而,这个转换实际上是有效的,带有一个未经检查的转换警告:

    List<? extends List<Number>> list3 = new ArrayList<>();
    List<List<Double>> list4 = (List<List<Double>>) list3;  // unchecked cast warning, but legal

当上面的第一次强制转换是非法的时,我该如何推断List&lt;Double&gt; 属于List&lt;Number&gt; 给出的类型家族?

在 Intellij 中使用 javac 1.8.0_144:

【问题讨论】:

  • 检查java中协变和逆变的概念。这篇文章可能会有所帮助:dzone.com/articles/covariance-and-contravariance
  • List&lt;Double&gt; 不是List&lt;Number&gt; 的子类型,所以我们知道List&lt;? extends List&lt;Number&gt;&gt; 绝对不是List&lt;List&lt;Double&gt;&gt;。从前一种类型到后一种类型的转换原则上可以在编译时被证明是不正确的。您的编译器可能无法识别,或者它只是选择警告而不是发出错误。这可能构成编译器错误。
  • 哈?什么javac 版本?
  • @Eugene 这是使用 javac 1.8.0_144。添加了未经检查的强制转换警告的屏幕截图。
  • 不是 javac。尝试从你的终端编译同样的东西。

标签: java generics


【解决方案1】:

我不知道你用什么工具来编译这个,但是我还没有找到一个编译这个的jdk,从816

这是非法的:

List<? extends List<Number>> list3 = new ArrayList<>();
List<List<Double>> list4 = (List<List<Double>>) list3;

出于显而易见的原因。 ? extends List&lt;Number不可能是List&lt;Double&gt;的超类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多