Wildcard capture does not go more than one generic level deep. So while this works:
LinkedList<? extends Number> test = new LinkedList<Integer>();
This does not:
LinkedList<List<? extends Number>> numList = new LinkedList<List<Integer>>();
The most reasonable explanation I can think of is to think of generics as invariant at the outermost level. A LinkedList<List<Integer>>
is not a LinkedList<List<? extends Number>>
, even though a List<Integer>
is a List<? extends Number>
, for the same reason that a List<Dog>
is not a List<Animal>
even though a Dog
is an Animal
. Here, Dog
is to Animal
as List<Integer>
is to List<? extends Number>
.
Well, the Dog/Animal solution is ? extends
:
List<? extends Animal> animals = new List<Dog>();
Applying the same reasoning, the workaround is another ? extends
:
LinkedList<? extends List<? extends Number>> numList = new LinkedList<List<Integer>>();
However, you won't be able to add anything to this list because of the first ? extends
. The reference type variable numList
doesn't know which subtype of List<? extends Number>
it really is; it could be ArrayList<Integer>
, so Java cannot provide the type safety that such a thing can be added to such a LinkedList
. To maintain type safety, the compiler will only allow adding null
. You'll have to match the generic type parameters exactly, with no wildcards: LinkedList<List<Integer>> numList = new LinkedList<List<Integer>>();
. You can add a List<Integer>
to such a LinkedList
.
LinkedList<List<Number>> numList = new LinkedList<List<Number>>();
? – Alloy