java 赋值 不可重复,Java无法从原始泛型类型列表强制转换为通配符泛型类型列表[重复]...

// #1 (does compile)

List raw = null;

List> wild = raw;

// #2 (doesn't compile)

List raw = null;

List> wild = raw;

首先让我们弄清楚为什么这些实际上是无关的任务。也就是说,它们受不同的规则支配。

有一个

从原始类或接口类型(

§4.8

G

到窗体的任何参数化类型

G

1

,...,T

n

>

.

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

#2需要引用类型转换;但是它的问题是它不是

widening conversion

给定泛型类型声明

C

1

,...,F

n

>

n个

>0),则

参数化类型的

C

1

,...,T

n

>

,其中

T

i

n个

)是一种类型,是否都是以下类型:

C

1

,...,S

n

>

,其中

S

i

T型

(1¥

¤

n个

这是指JLS所说的

containment

,如果要成为有效的赋值,则左侧的参数必须

包含

右边的论点。包容在很大程度上控制了通用子类型,因为

"concrete" generic types

invariant

.

您可能熟悉以下想法:

List

List

但是

是一个

List extends Animal>

.

好吧,后者是真的,因为

? extends Animal

Dog

.

所以问题变成

“”执行类型参数

List>

包含原始类型参数

List

? 答案是否定的:尽管

列表>

列表

,此关系不适用于类型参数。

没有什么特别的规则可以证明这一点:

List>

不是的子类型

List

列表

不是的子类型

.

所以因为

列表

不是的子类型

,分配无效。同样,您不能执行

narrowing conversion

投球是因为

不是

列表gt;

或者。

// 1. raw type

@SuppressWarnings("unchecked")

List> list0 = (List) api();

// 2. slightly safer

@SuppressWarnings({"unchecked", "rawtypes"})

List> list1 = (List>) (List extends List>) api();

// 3. avoids a raw type warning

@SuppressWarnings("unchecked")

List> list2 = (List>) (List super List>>) api();

(您可以替换

JAXBElement

列表

这个铸件的用例应该是安全的,因为

列表gt;

是一种比

列表

这个

语句是加宽强制转换,然后是未选中的赋值。这是因为,如上所示,任何参数化类型都可以转换为其原始类型,反之亦然。

这个

稍微安全一点

语句(这样命名是因为它丢失的类型信息更少)是加宽型转换,然后是窄型转换。它通过投射到一个常见的超类型来工作:

List extends List>

â± â²

List> List

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

事实上

List extends List>

被认为是

可通过传递性证明:

? extends List

包含

? extends List>

列表

列表>

?扩展列表>

包含

列表>

因此

?扩展列表

列表>

(也就是说,

List extends List> :> List extends List>> :> List>

.)

第三个示例的工作方式与第二个示例类似,它将强制转换为一个通用的超类型

List super List>>

这里的非技术性总结是,规范意味着在

列表

列表gt;

尽管从

列表

应该是

安全的

列表

可以储存任何种类的

列表

,但是

对检索后如何使用其元素施加了更多限制。)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值