0

我正在尝试创建一个通用列表,该列表将包含从 Object 继承的任何类型的项目(我假设每个对象都是 object 类型)。

但是,在下面的情况下,当我尝试添加一个字符串(从对象继承)时,它在 Eclipse 中显示错误

Error:-The method add(capture#1-of ? extends Object) in the type List<capture#1-of ? extends Object> is not applicable for the arguments (String)


List<? extends Object> alist = new ArrayList<Object>();
alist.add("USA");

有人可以解释为什么我会收到此错误吗?

4

5 回答 5

6

原因是它<? extends Object>可以代表 的任何子类Object,这可能与String. 可能是List<Integer>

List<? extends Object> alist = new ArrayList<Integer>();  // works
alist.add("USA");  // Should you be allowed to do this?  No!

为了类型安全,您不应该执行这样的add操作。因此,不允许此操作。

解决方法是消除变量声明中的通配符:

List<Object> alist = new ArrayList<Object>();

现在任何Object或子类都可以传递给add.

于 2013-10-02T18:52:06.983 回答
0

您的案例是有效 Java 的PECS 助记符可能有所帮助的另一个示例。

alist是一个消费者,这意味着你希望它(消费)有新的对象添加到它。那么,从 PECS,您应该使用Collection<? super Thing>

List<? super Object> alist = new ArrayList<Object>();
alist.add("USA");

这样,您就可以.add()随时Object进入alist. (并且因为"USA"Object,所以您可以毫无问题地添加它。)

请注意,super在您的类型中使用...

List<? super Object> alist = new ArrayList<Integer>(); // notice <Integer> here
alist.add("USA");

...第一行将正确地产生错误,因为Integer它不是Object.

当然,这有点令人困惑是很自然的,因为Object它没有超类,并且没有类是 的超类ObjectList<? super Object> alist =因此,实际上,赋值唯一可能的右侧是 a List<Object>(或任何实现的类List,由于多态性)。

在此处阅读有关 PECS 的更多信息

在此处阅读 Effective Java 一书中的 PECS 说明。

于 2013-10-02T19:09:41.507 回答
0

您正在尝试的问题如下

List<? extends Object> alist = getList(); // returns a List<Dog>
alist.add("USA"); // would fail at runtime

因此编译器不允许您添加任何List由通配符绑定的内容。

于 2013-10-02T18:52:32.300 回答
0

奇怪的短语? extends Object意味着也可以将集合的所有成员添加到任何类型的元素中,这些元素是 Object 的子类型。

由于所有类型都继承 Object 你可以只写List<Object>

List<Object> alist = new ArrayList<Object>();
alist.add("USA");
于 2013-10-02T18:52:40.143 回答
0

您需要<? super String>将字符串或其任何超类添加到列表 iirc。或者只是<?>为了任何事情。

请参阅下界通配符:http ://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html

于 2013-10-02T18:53:17.263 回答