栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

无法从列表转换 列出>

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

无法从列表转换 列出>

// #1 (does compile)
List raw = null;
List<?> wild = raw;

// #2 (doesn't compile)List<List> raw = null;List<List<?>> wild = raw;

首先让我们弄清楚为什么这些实际上是不相关的分配。也就是说,它们受不同规则的约束。

#1称为
未经检查的转换

存在 未检查的转换
从原始类或接口类型(§4.8)

G
的任何参数化的类型的形式的。
G<T1,...,Tn>

具体地说,这是仅在这种情况下的
分配上下文的
一种特殊情况:

如果在应用了[其他可能的转换]之后,结果类型为原始类型,则可以应用未经检查的转换。

#2需要引用类型转换;但是,它的问题在于它不是
扩展转换
(这是一种无需转换就可以隐式允许的引用转换)。

这是为什么?好吧,这特别受通用子类型的规则支配,更具体地讲,要点如下:

给出一个通用的类型声明( Ñ > 0),则 直接超 参数化类型的,其中,(1≤ Ñ
)是一种类型的,是以下所有:

C<F1,...,Fn>
C<T1,...,Tn>``Ti

  • C<S1,...,Sn>
    ,其中包含(1≤ Ñ )。
    Si``Ti

这就是JLS所称的
containment
,这是有效的赋值,左侧的参数必须 包含
右侧的参数。由于“具体”泛型类型是不变的,因此包含在很大程度上决定了泛型子类型。

您可能熟悉以下想法:

  • 一个
    List<Dog>
    不是一个
    List<Animal>
  • 但是a
    List<Dog>
    是一个
    List<? extends Animal>

好吧,后者是正确的,因为

? extends Animal
contains
Dog

因此问题变成
“类型参数是否

List<?>
包含原始类型参数
List
?答案是否定的:尽管
List<?>
是的子类型
List
,但此关系不适用于类型实参。

没有任何特殊的规则可以使它成立:

List<List<?>>
List<List>
本质
List<Dog>
上讲,不是的子类型也不是的子类型
List<Animal>

因此,由于

List<List>
不是的子类型
List<List<?>>
,因此分配无效。同样,您不能执行直接
缩小转换强制转换,
因为它既不是二者
List<List>
的超类
List<List<?>>


要进行分配,您仍然可以应用强制转换。在我看来,有三种方法可以做到。

// 1. raw type@SuppressWarnings("unchecked")List<List<?>> list0 = (List) api();// 2. slightly safer@SuppressWarnings({"unchecked", "rawtypes"})List<List<?>> list1 = (List<List<?>>) (List<? extends List>) api();// 3. avoids a raw type warning@SuppressWarnings("unchecked")List<List<?>> list2 = (List<List<?>>) (List<? super List<?>>) api();

(您可以替换

JAXBElement
内部
List
。)

此类型转换的用例应该是安全的,因为

List<List<?>>
它比更具限制性
List<List>

  • 原始类型 语句是拓宽投选中,然后分配。之所以可行,是因为如上所述,任何参数化类型都可以转换为其原始类型,反之亦然。

  • 稍微安全的 声明(如此命名是因为它失去了较少类型信息)是拓宽投则投缩小。这通过强制转换为普通的超类型来工作:

        List<? extends List>    ╱         ╲

    List<List<?>> List

有界通配符允许将类型参数考虑为通过包含进行子类型化。

List<? extends List>
被认为是超类的事实
List<List<?>>
可以通过传递性来证明:

1. `? extends List`包含`? extends List<?>`,因为`List`是的超类型`List<?>`。2. `? extends List<?>`包含`List<?>`。3. 因此`? extends List`包含`List<?>`。

(即

List<? extends List> :> List<? extends List<?>> :> List<List<?>>
。)

  • 第三个示例的工作方式与第二个示例类似,通过强制转换为通用超类型
    List<? super List<?>>
    。由于它不使用原始类型,因此我们可以减少一个警告。

这里的非技术性总结是,规范意味着有间既不亚型也不超关系

List<List>
List<List<?>>

虽然从转换

List<List>
List<List<?>>
应该是 安全的
,这是不允许的。(这是安全的,因为两者都是
List
可以存储任何类型的
List
,但是
List<List<?>>
对检索元素后如何使用它施加了更多限制。)

不幸的是,除了原始类型是奇怪的而且它们的使用有问题之外,没有任何实际原因无法编译。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/394845.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号