如何将`MyClass`添加到`List<? extends MyClass>`中?

4

我有一个Java类,其中包含继承自MyClass的对象子项。

class MyClass {
List<? extends MyClass> items;
[...]

出于某种原因,我无法将MyClass项插入到此列表中。我不明白为什么,也不知道如何解决这个问题。例如:

void foo(){
  items = new LinkedList<MyClass>(); // This is OK
  items.add(new MyClass()); // Not allowed... why?
}

编译器说:“List中的add(capture#1-of ? extends MyClass)方法不适用于参数(MyClass)

我真的不明白如何绕过这个问题,为什么编译器只接受必须扩展MyClass类型。

注意:为什么需要使用这种方法?因为我需要允许扩展MyClass以拥有子项的列表。


为什么第一行是 Myclass 而不是 MyClass - user202729
如果你只想将 MyClass 的任何子类的实例添加到 items 中,那么 ? extends 部分实际上是不需要的:List<MyClass> 将接受任何类型为 MyClass 或从 MyClass 继承的任何类的实例... - moilejter
我认为符号 <? extends MyClass> 的含义是“某个继承自MyClass的类,或者就是MyClass本身” - 但是在这种类型中没有足够的信息让编译器知道你想使用哪个MyClass的子类型... - moilejter
3个回答

6

List<? extends MyClass> items 的意思是类型参数是一个未知的类型,该类型可以分配给 MyClass

例如,它可能是一个由 MySubClass 组成的 List

public MySubClass extends MyClass{}

List<? extends MyClass> items = new ArrayList<MySubClass>();

现在考虑你有一个扩展了 MyClassMyAnotherSubClass:
public MyAnotherSubClass extends MyClass{}

MyClass item = new MyAnotherSubClass(); // refer it using MyClass

显然,List<MySubClass> 不应该包含 MyAnotherSubClass
items.add(item); // compile error

4

The declaration

List<? extends MyClass> items;

说的是,items 是一个类型参数未知但可能是 MyClass 或其子类的 List

仔细看一下,这就解释了为什么往这样的 List 中添加 任何内容 都不是类型安全的:它的类型参数是 未知的。如果它恰好是 MySubClass1,那么添加 MyClassMySubClass2 都是不正确的。如果它恰好是 MySubClass2,那么添加 MySubClass1 也是不正确的。根本没有任何类型可以被安全地添加。

如果你想要一个列表,可以向其中添加类型为 MyClass 的对象以及 MyClass 的任何子类对象,那么你可能只需要使用 List<MyClass>

从技术上讲,List<? super MyClass> 也可以满足特定的目的,但是会遇到相反的问题:不能安全地假设列表元素比 Object 更具体的任何类型。


1
使用extends只能从集合中获取,不能向其中添加内容。您可以使用super来实现。因此,在您的情况下,如果您使用- List<? super MyClass> items;,将不会出现任何编译/运行时错误。尽管super允许获取和添加,但在获取时返回类型为? super T

哇!这就是它!我尝试过的其他方法都有其缺点: 使用List <? extends MyClass>,我无法添加任何内容。 使用List<MyClass>,我需要在getter上强制转换所有元素,并且实际上不能使用任何setter。 这种方式只需在获取时转换元素,因此可以编写,例如, List <? super MyClass> _items = getItems(); if (_items == null) _items = new LinkedList<MyClass>(); MyClass item = (MyClass)_items.get(0); 并且 items.add(new MyClass()); 谢谢。 - donnadulcinea
很高兴能帮忙 :) - Ashishkumar Singh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接