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<Child>, or a
List<GrandChild>.” That makes it safe to fetch any items out of the
List<T> API and convert from
Parent, but it’s not safe to call in to the
List<T> API converting from
T… because that conversion may be invalid.