另一个例子非常复杂,我根本不理解它,我的问题在某种程度上是类似的,但正如我所说的那样更简单,可能会在更简单的答案中产生
public List<? extends Parent> myfunction(List<? extends Parent> mylist){
mylist.add(new Child()) ; //Doesn't Compile
}
答案 0 :(得分:8)
我相信你正在寻找一个获取列表,添加内容然后返回列表的方法。该列表是通用的,您希望返回类型与参数的类型匹配。
在一般情况下,您就是这样做的:
public <T extends Parent> List<T> myfunction(List<T> myList) {
... // Add something to myList
return myList;
}
具体而言,您正尝试将new Child()
添加到myList
。这不行。可以使用多种列表调用myfunction()
,而添加new Child()
只有在列表为List<Parent>
或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>());
在最后一行中,使用myfunction()
对象列表调用OtherChild
。显然,在这样的列表中添加Child
对象是非法的。编译器通过拒绝myfunction()
<强>附录强>
如果您希望myfunction()
能够向myList
添加元素,则需要使用工厂(因为Java不允许new T()
其中T是类型参数 - 由于type erasure)。以下是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;
}
现在,它的用法:
public static class ChildOfOtherChild extends OtherChild {}
myfunction(new ArrayList<OtherChild>(), new Factory<ChildOfOtherChild>() {
@Override public ChildOfOtherChild create() { return new ChildOfOtherChild(); }
});
}
答案 1 :(得分:5)
List<? extends Parent>
的含义是“只包含某些未知子类Parent
的实例的列表” - 由于您不知道它是哪个子类,因此除了{之外不能添加任何内容{1}}到列表中(你可以从中获取null
个实例)。
如果您要将特定的子类Parent
添加到列表中,那么您真正需要的是:
Child
答案 2 :(得分:1)
关注Jon Skeet在other question中的示例,假设您使用了
public List<? extends Fruit> myfunction(List<? extends Fruit> mylist){
mylist.add(new Apple()) ; //Doesn't Compile
return myList;
}
然后用
调用它List<Banana> bananas = new ArrayList<Banana>();
bananas = myfunction(bananas);
您无法将苹果添加到香蕉列表中。
可以做的是
public List<Fruit> addApple(List<Fruit> mylist){
mylist.add(new Apple()) ;
return myList;
}
public List<Fruit> addBanana(List<Fruit> mylist){
mylist.add(new Banana()) ;
return myList;
}
答案 3 :(得分:-2)
如何添加return
语句,或声明方法返回void
...