繁体   English   中英

警告不必要与泛型集合?

[英]Warning unnecessary with generic collections?

我不知道为什么Java编译器不信任这一行代码:

List<Car> l = new ArrayList();

并期望有一个类型化的ArrayList:

List<Car> l = new ArrayList<Car>();

确实,编译器在第一种情况下指示未经检查的分配。

为什么编译器没有看到此ArrayList()刚刚被创建,因此无法在其中找到“ Car”以外的其他对象?

如果未类型化的ArrayList是在以前创建的,但在这种情况下没有创建,则此警告才有意义。

实际上,由于List的类型为“ Car”,因此仅当“ object”为“ Car”时,才允许所有期货“ l.add('object')”。 =>因此,根据我的说法,不会发生任何意外。

我错了吗 ?

谢谢

为什么编译器没有看到此ArrayList()刚刚被创建,因此无法在其中找到“ Car”以外的其他对象?

简单的答案是“因为不允许这样做”。

编译器必须实现Java语言规范。 如果某个编译器编写者去编译器添加了很多技巧,以使“每个人”都知道是安全的,那么他实际上所做的就是引入可移植性问题。 使用笨拙的(或更准确地说,严格符合标准的)Java编译器进行编译时,使用此编译器编译和测试的代码将产生编译错误。

那么,JLS为什么不允许这样做? 我可以想到一些可能的解释:

  • JLS编写者没有时间将其添加到规范中。 例如,考虑本规范其余部分的所有分支。
  • JLS编写者无法在规范中找到表达这种声音的合理方法。
  • JLS编写者不想在规范中加入他们不确定在现实世界中的编译器中是否可以实现的规范……而不会给编译器编写者带来太多负担。

然后还有一个相关的问题,即编译器是否可以实现这种检查。 我没有资格回答这个问题……但是我对这个问题了解得足够多,以至于认识到它不一定像人们想象的那么简单。

要添加到Stephen C的非常好的答案(主要是因为将其作为注释编写起来确实很麻烦,很抱歉),实际上在JLS中明确提到了此问题:

讨论区

可以从任何类型的参数实例的值中分配原始类型的变量。

例如,可以根据子类型化规则(第4.10.2节)将Vector<String>分配给Vector<String>

从Vector到Vector<String>的反向分配是不安全的(因为原始向量可能具有不同的元素类型),但是仍然允许使用未经检查的转换(第5.1.9节),以便实现与旧代码的接口。 在这种情况下,编译器将发出未经检查的警告。

为什么他们在这种特殊情况下没有特殊情况? 因为不必为实现添加特殊情况,而不必这样做,并且“正确的”解决方案不会添加任何特殊的问题(除了一些写作工作,他们认为这不太重要) 。

同样,每种特殊情况都意味着编译器会变得更加复杂(至少可以说,在这种情况下当然也是如此)-考虑到javac整体上有多么简单,我想拥有一个简单,快速的编译器也是不二之选。设计目标。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM