如何将 `MyClass` 添加到 `List<?扩展我的类>`

How may I add `MyClass` to `List<? extends MyClass>`

我有一个 Java Class,其中包含扩展 MyClass 的对象的子项。

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

出于某种原因,我无法将 MyClass 项目插入到此列表中。我不明白为什么,以及如何绕过这个问题。例如:

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

编译器说“类型列表中的方法 add(capture#1-of ? extends MyClass) 不适用于参数 (MyClass)"

我真的不明白如何绕过这个问题,以及为什么编译器只接受必须扩展 MyClass.[=12= 的类型]

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

List<? extends MyClass> items表示类型参数是未知类型,可分配给MyClass

例如,它可以是 MySubClassList:

public MySubClass extends MyClass{}

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

现在考虑你有 MyAnotherSubClass 也从 MyClass 延伸:

public MyAnotherSubClass extends MyClass{}

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

显然,List<MySubClass> 不应包含 MyAnotherSubClass:

items.add(item); // compile error

宣言

List<? extends MyClass> items;

表示 items 是一个 List ,其类型参数不完全已知,但可以是 MyClass 或子类。

仔细阅读。它解释了为什么将 anything 添加到这样的 List 不是类型安全的:它的类型参数是 unknown。如果恰好是MySubClass1,那么加一个MyClass或者一个MySubClass2是不正确的。如果刚好是MySubClass2,那么加一个MySubClass1是不正确的。根本没有可以安全添加的类型。

如果您想要一个 List,您可以向其中添加 MyClass 类型的对象以及 MyClass 的任何子类的对象,那么您可能只是在寻找 List<MyClass>.

从技术上讲,List<? super MyClass> 也可以用于该特定目的,但是您会遇到相反的问题:假定列表元素是比 [= 更具体的任何类型都是类型不安全的25=].

使用 extends 你只能从 collection 获得。你不能把它放进去。您可以使用 super 来做到这一点。

因此,在您的情况下,如果您使用 - List<? super MyClass> items;,您将不会收到任何 compilation/runtime 错误。

虽然super允许get和put,但是get中的return类型是? super T