Java:不能通用List <?扩展Parent> mylist

Ism*_*ush 1 java generics collections inheritance list

另一个例子非常复杂,我根本不理解它,我的问题在某种程度上是相似的,但正如我所说的那样更简单,可能会在更简单的答案中产生

public List<? extends Parent> myfunction(List<? extends Parent> mylist){
       mylist.add(new Child())  ; //Doesn't Compile
}
Run Code Online (Sandbox Code Playgroud)

Ita*_*man 8

我相信你正在寻找一种方法,它采用一个列表,添加一些东西,然后返回列表.该列表是通用的,您希望返回类型与参数的类型匹配.

在一般情况下,这是你如何做到的:

public <T extends Parent> List<T> myfunction(List<T> myList) {
   ... // Add something to myList
   return myList;
} 
Run Code Online (Sandbox Code Playgroud)

具体来说,你想添加new Child()myList.这不行.myfunction()可以使用多种列表调用,而添加new Child()只能在列表为a List<Parent>或a 时才有效List<Child>.以下是不同类型List的示例:

public static class Parent {}  
public static class Child extends Parent {}  
public static class OtherChild extends Parent {}

public <T extends Parent> List<T> myfunction(List<T> myList) {
  myList.add(new Child());
  return myList;
} 

myfunction(new ArrayList<OtherChild>());
Run Code Online (Sandbox Code Playgroud)

在最后一行中,myfunction()使用List OtherChild对象调用.显然,将Child对象添加到这样的列表中是非法的.编译器通过拒绝定义来阻止它myfunction()

附录

如果你想myfunction()能够添加一个元素myList需要使用工厂(因为Java不允许new T()T是一个类型参数 - 由于类型擦除).这是myfunction()应该如何看起来像:

public interface Factory<T> {
  public T create();
}

public <T extends Parent> List<T> myfunction(List<T> myList, 
                                             Factory<? extends T> factory) {
  myList.add(factory.create());
  return myList;
} 
Run Code Online (Sandbox Code Playgroud)

现在,它的用法:

public static class ChildOfOtherChild extends OtherChild {}

myfunction(new ArrayList<OtherChild>(), new Factory<ChildOfOtherChild>() {
    @Override public ChildOfOtherChild create() { return new ChildOfOtherChild(); }
  });
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*rdt 5

什么List<? extends Parent>意思是"只包含一些未知子类的实例的列表Parent" - 并且由于你不知道它是什么子类,你不能添加除null列表之外的任何东西(你可以从中获取Parent实例).

如果您有一个特定的子类Child要添加到列表中的实例,那么您真正需要的是:

public List<Child> myfunction(List<Child> mylist)
Run Code Online (Sandbox Code Playgroud)