繁体   English   中英

Java中的泛型和参数化类型

[英]Generics and parameterized types in Java

以下代码导致编译时错误:

类型List中的方法add(capture#1-of?extends Object)不适用于参数(String)

代码:

List<? extends Object> a1 = new ArrayList();
a1.add("string");

错误在线:

a1.add("string");

由于类String从Object扩展,为什么ref a1不接受String类型?

? extends Object ? extends Object表示“一些未知类型X延伸Object ”。 通过尝试向集合添加String ,您实际上声称X = String ,编译器无法验证。 就编译器而言, X也可以是Integer或完全不同的东西。

换句话说List<? extends Object> List<? extends Object>并不意味着“任何扩展Object东西”。 一个简单的List<Object>意味着。

我建议阅读这篇文章, http://java.dzone.com/articles/covariance-and-contravariance (斜体添加是我的)

总之,我们使用协方差<? extends Object> 当我们只打算从结构中取出泛型值时, <? extends Object> 我们使用逆变<? super Object> <? super Object>当我们只打算将泛型值放入一个结构中时,当我们打算同时执行这两个操作时,我们使用一个不变的<Object>

您将列表定义为持有协变对象类型,这意味着您可以编写Object o = a1.get(1)但不能编写a1.add("foo") 如果你想能够添加对象而不是让它们回来,那么你需要像这样定义你的列表:

List<? super Object> a1 = new ArrayList<>();

这有点不幸,在我看来,语言作者使用术语extendsuper来表示协方差和逆变,特别是在上面的例子中,因为没有超类型的Object

List<? extends Object> List<? extends Object>可用于每种类型的列表。

您如何看待,例如,让它添加任何对象是否安全?

List<? extends Object> a1 = new ArrayList<Integer>();
a1.add("string");

只有安全值才能为null因为它不属于任何特定类型。

要解决此问题,您可以使用例如List<String> a1 = new ArrayList<String>()List a1 = new ArrayList()

暂无
暂无

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

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