关于Java:我怎么可以把”MyClass”添加到列表LT?扩展myClass

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

本问题已经有最佳答案,请猛点这里访问。

我有一个Java类,它包含扩展MyClass的对象的子项。

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

由于某些原因,我无法将MyClass项插入此列表。我不明白为什么,也不知道如何绕过这个问题。例如:

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

编译器说"方法添加(捕获1-of?"扩展类型列表中的MyClass)不适用于参数(MyClass)""

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

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


List items表示类型参数为未知类型,可分配给MyClass使用。

例如,它可以是MySubClassList

1
2
3
public MySubClass extends MyClass{}

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

现在考虑您的MyAnotherSubClass也从MyClass延伸出来:

1
2
3
public MyAnotherSubClass extends MyClass{}

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

显然,不应允许List含有MyAnotherSubClass

1
items.add(item); // compile error

宣言

1
List<? extends MyClass> items;

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

仔细阅读。它解释了向这样一个List中添加任何内容是不安全的类型:它的类型参数未知。如果恰好是MySubClass1,那么添加MyClassMySubClass2是不正确的。如果恰好是MySubClass2,那么添加MySubClass1是不正确的。根本没有可以安全添加的类型。

如果你想要一个List,你可以添加MyClass类型的对象,也可以添加MyClass任何子类的对象,那么你可能只是在寻找List

从技术上讲,List也可以用于特定目的,但您会遇到与此相反的问题:假定list元素是比Object更具体的类型是不安全的。


使用extends只能从集合中获得。你不能放进去。你可以用super来实现。

因此,在您的情况下,如果使用-List items;,您将不会得到任何编译/运行时错误。

虽然super同时允许get和put,但get时的返回类型是? super T