List<? extends Bird> could be List<Bird> or List<Sparrow>. Line #7 doesn't compile because we can't add a Sparrow to List<Bird>
The above underlined is factually incorrect. Sparrow can be added to List<Bird>. Or atleast it is not convincingly explained why compilation fails. Could some help me understand why Line #6 not compile?
Right, a List<Sparrow> is a subtype of List<? extends Bird> but it isn't a subtype of List<Bird>. That means you could assign things like this:-If you had the List you showed in your second code block, you could get Sparrows out of it, but one of its elements isn't a Sparrow. Goodbye type‑safety. Remember that writing <...> instructs the compiler to go into fusspot mode and warn you about every tiny possible doubt and refuse to compile all sorts of things so as to maintain type‑safety. So you can only add one thing to a List<? extends Anything> and that is the one thing you can safely cast to any type: null.