f.khantsis
f.khantsis

Reputation: 3540

why can't List<? extends List<T>> be assigned to List<List<T>>

My class has a property that is a two dimensinal list of a certain class T.

It seems that it is logical to create this property as a List<? extends List<T>>, thus allowing it to be assigned List<ArrayList<T>> or List<LinkedList<T> in addition to List<List<T>>.

It also seems logical that my getter will return a List<List<T>>, since we don't need to tell Consumers that what this list can be assigned since the consumer will asign the object he gets from the getter to a variable, and not the other way around.

However, my getter refuses to automatically convert List<? extends List<T>> to List<List<T>>, throwing an IncompatibleType error. Why can't it be coerced?

Upvotes: 2

Views: 643

Answers (1)

Tamas Rev
Tamas Rev

Reputation: 7166

@JB-Nizet explained the reason pretty well: it would allow you to add an ArrayList to a list of LinkedList -s.

The short answer is, of course, you cannot do that because the compiler will not let you do that ;)

Let me show you another example. You basically cannot add anything to such collections:

List<? extends List<T>> list = new ArrayList<>();
list.add(new LinkedList<T>()); // compile error
list.add(new ArrayList<T>()); // compile error
List<T> sublist = new ArrayList<>();
list.add(sublist); // compile error

If this is what you want, then you can just use whatever list type within your getter and return the wildcard-type:

public List<? extends List<T>> getSomething() {
    List<ArrayList<T>> list = new ArrayList<>();
    // do something
    return list; // List<ArrayList<T>> converts automatically to List<? extends List<T>
}

If you want clients to add stuff to this list but not remove, then you can use the super keyword:

List<? super ArrayList<T>> list = new ArrayList<>();
list.add(new ArrayList<T>()); // this is fine

On the other hand, if you want to allow both operations, then simply don't use a wildcard:

public List<List<T>> getSomething() {
    return new ArrayList<>();'
}

Upvotes: 1

Related Questions