java .<>,java – 为什么不允许转换为“GenericType <?>”?

博客探讨了Java中泛型类型的显式转换,以及编译器对此的处理。文章通过各种通配符组合分析了哪些转换应该是合法的,并指出在某些情况下,javac编译器可能存在的不一致。作者提出,当编译器不允许有意义的转换时,可能是规则问题或编译器bug。文章强调理解类型转换的意义以及编译器的限制在编程中的重要性。
摘要由CSDN通过智能技术生成

如果程序员想要将类型X显式地转换为类型Y,那么语言可以允许它,假设程序员比编译器更了解.

但是,这些规则有什么问题吗?并且,编译器是否符合这些规则? ……这些问题太复杂,不太有趣.

我们应该关心的是演员是否有意义;如果它确实有意义,并且编译器拒绝接受它,没问题,只需解决它.

在你的问题中,有两个地方可以插入通配符,在Foo< >,并且在Iterable

0. None

1. Bounded "? extends Something"

2. Unbounded "?"

所以让我们探索所有组合,这是我的结论:

wildcard#1 wildcard#2 should_compile javac eclipse

00 - - Y Y N

01 - ? extends N N N

02 - ? N N N

10 ? extends - Y N Y

11 ? extends ? extends Y N Y

12 ? extends ? Y Y Y

20 ? - Y Y Y

should_compile意味着演员是否有意义,稍后会解释.

在第10和第11例中,代码应该编译,但javac拒绝它.要么规则有问题,要么javac有bug.

让我们看看例如,为什么案例00有意义并且应该编译

void test00(Foo> foo) {

Bar> bar = (Bar>) foo;

}

the question is, could there be a class/interface `X`, such that

Bar <: foo>>

=> Foo> <: foo>>

=> Iterable = Iterable

=> X = String

so the answer is yes, the cast makes sense.

以及为什么案例01不应该编译

Foo> <: foo extends string>>

=> Iterable = Iterable extends String>

=> NO SOLUTION

note that Iterable != Iterable extends String>

和案例11

Foo> <: foo extends iterable string>>

=> Iterable <: iterable extends string>

=> X <: string>

令人惊讶的是,案例01不应该编译,尽管它感觉合情合理.根本问题是,Iterable是可变的,我们应该在它使用的任何地方使用通配符.理想情况下我们应该宣布

class Bar implements Foo>

但如果我们到处都插入通配符,那么生活就是地狱.更好的解决方案是声明站点差异.不确定Java是否会在我们退休之前添加该功能.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值