如何将MyClass添加到List <!-?扩展MyClass->`

时间:2018-08-27 04:05:41

标签: java generics inheritance extends

我有一个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?
}

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

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

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

3 个答案:

答案 0 :(得分:6)

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

例如,它可能是List中的MySubClass

public MySubClass extends MyClass{}

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

现在考虑您也拥有MyAnotherSubClass的{​​{1}}:

MyClass

很显然,public MyAnotherSubClass extends MyClass{} MyClass item = new MyAnotherSubClass(); // refer it using MyClass 不应包含List<MySubClass>

MyAnotherSubClass

答案 1 :(得分:4)

声明

List<? extends MyClass> items;

items是一个List,其类型参数并不确定,但可以是MyClass或子类。

请仔细阅读。它解释了为什么向这样的List中添加任何内容是不安全的:其类型参数为 unknown 。如果恰好是MySubClass1,则添加MyClassMySubClass2是不正确的。如果恰好是MySubClass2,则添加MySubClass1是不正确的。完全没有可以安全添加的类型。

如果您想为List添加类型MyClass的对象以及MyClass的任何子类的对象,那么您可能只是在寻找List<MyClass>

从技术上讲,List<? super MyClass>也可以达到特定的目的,但是您会遇到相反的问题:假定列表元素是比{{1}更具体的类型,这在类型上是不安全的。 }。

答案 2 :(得分:1)

使用extends只能从集合中获取。你不能放进去。您可以使用super来完成。

因此,就您而言,如果您使用-List<? super MyClass> items;,则不会收到任何编译/运行时错误。

尽管super允许获取和放置,但获取期间的返回类型为? super T