Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Can't to generic List<? extends Parent> mylist

The other Example is pretty 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
}
like image 362
Ismail Marmoush Avatar asked Dec 08 '25 10:12

Ismail Marmoush


2 Answers

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(); }
  });
}
like image 173
Itay Maman Avatar answered Dec 10 '25 01:12

Itay Maman


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)
like image 39
Michael Borgwardt Avatar answered Dec 10 '25 01:12

Michael Borgwardt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!