This is basically the same case as the previous one. Basically, in the case of generics, you are never allowed to do this:
Think of this example:
ArrayList<Object> alist = new ArrayList<Number>();
This does not compile because it is not a safe type. You can add Strings aList. You are trying to assign a list of objects that are guaranteed to be numbers, but can be any number, into a list that guarantees that you will contain objects, but these can be any objects. If the compiler allowed this case, it would relax the restriction on what types of objects can be listed. This is why you should use a wildcard ?, as such:
ArrayList<? extends Object> alist = new ArrayList<Number>();
To the compiler ArrayList<? extends Object> ArrayList<? extends Object> means "ArrayList of a specific type"? that I donβt know, but which, as I know, extends Object. This ArrayList is guaranteed to contain only elements of this unknown '?' type and therefore only contains objects. "In this case, the compiler, however, will not allow you to do alist.add (2). Why is this because the compiler does not know the type of list items and cannot guarantee that you are allowed to insert into him Integer objects.
Are you right in thinking that D<? extends Object> D<? extends Object> is a supertype of D<? extends C> D<? extends C> . However, List<D<? extends Object>> List<D<? extends Object>> not a subtype of List<D<? extends C>> List<D<? extends C>> , you should use List<? extends D<? extends C>> List<? extends D<? extends C>> List<? extends D<? extends C>> .
Your case is basically equivalent
ArrayList<D<? extends Object>> alist = new ArrayList<D<? extends C>>();
You have the same problem as above, the list on the right side can only contain an object of class D, the type of which is parameter C, and you try to assign it to the list (on the left) it can contain objects of class D, the type parameter of which can be any object .
So, if the compiler assumed that your code would not be type safe, and the following would fail.
ArrayList<D<? extends Object>> alist = new ArrayList<D<? extends C>>();
In short, what you need for your specific example:
// type parameter of left hand side is ? extends subtype List<? extends D<? extends Object>> b = Arrays.asList(new D<A>(), new D<B>()); // type parameter of left hand side is identical List<D<? extends C>> b = Arrays.asList(new D<A>(), new D<B>()); // type parameter of left hand side is ? extends subtype List<? extends D<? extends C>> c = Arrays.asList(new D<A>()); // type parameter of left hand side is identical List<D<A>> c = Arrays.asList(new D<A>());
Hope this helps.