Java: Can't to generic List<? extends Parent> mylist
The other Example is prett开发者_运维问答y complex and I didn't understand it at all, my problem is similar somehow but as I said it's simpler and might yield in simpler answer
public List<? extends Parent> myfunction(List<? extends Parent> mylist){
mylist.add(new Child()) ; //Doesn't Compile
}
I believe you're looking for a method that takes a list, adds something to it, and then returns the list. The list is generic and you want the return type to match the type of the parameter.
Here's how you do it, in the general case:
public <T extends Parent> List<T> myfunction(List<T> myList) {
... // Add something to myList
return myList;
}
Specifically, you're trying to add new Child()
to myList
. This cannot work. myfunction()
may be called with many kinds of lists, whereas adding new Child()
can only work if the list is either a List<Parent>
or a List<Child>
. Here's an example for a List of different kind:
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>());
In the last line, myfunction()
is called with a List of OtherChild
objects. Obviously, adding a Child
object into such a list is illegal. The compiler prevents that by rejecting the definition of myfunction()
Appendix
If you want myfunction()
to be able to add an element to myList
you need to use a factory (since Java does not allow new T()
where T is a type parameter - due to type erasure). Here's how myfunction()
should look like:
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;
}
And now, its usage:
public static class ChildOfOtherChild extends OtherChild {}
myfunction(new ArrayList<OtherChild>(), new Factory<ChildOfOtherChild>() {
@Override public ChildOfOtherChild create() { return new ChildOfOtherChild(); }
});
}
What List<? extends Parent>
means is "a list that contains only instances of some unknown subclass of Parent
" - and since you don't know what subclass it is, you can't add anything except null
to the list (you can get Parent
instances from it, though).
If you have a specific subclass Child
that you want to add instances of to the list, then what you really need is this:
public List<Child> myfunction(List<Child> mylist)
Following on Jon Skeet's example in the other question, let's say you used
public List<? extends Fruit> myfunction(List<? extends Fruit> mylist){
mylist.add(new Apple()) ; //Doesn't Compile
return myList;
}
but then called it with
List<Banana> bananas = new ArrayList<Banana>();
bananas = myfunction(bananas);
You can't add an apple to a list of bananas.
What you can do is
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;
}
What about adding a return
statement, or declare the method to return void
...
精彩评论