It’s doing that for the sake of safety. Imagine if it worked:
List<Child> childList = new ArrayList<Child>();
childList.add(new Child());
List<? extends Parent> parentList = childList;
parentList.set(0, new Parent());
Child child = childList.get(0); // No! It's not a child! Type safety is broken...
The meaning of List<? extends Parent>
is “The is a list of some type which extends Parent
. We don’t know which type – it could be a List<Parent>
, a List<Child>
, or a List<GrandChild>
.” That makes it safe to fetch any items out of the List<T>
API and convert from T
to Parent
, but it’s not safe to call in to the List<T>
API converting from Parent
to T
… because that conversion may be invalid.