As you have discovered by yourself, an ArrayList declared as ArrayList<? extends Foo> subFoos = new ArrayList<>(); would not be very useful.
In order to see the usefulness of <? extends T> consider this:
List<Foo> collect( List<? extends Foo> a1, List<? extends Foo> a2 ){ List<Foo> collected = new ArrayList<>(); collected.addAll( a1 ); collected.addAll( a2 ); return collected;}which can later be used as follows:
List<Foo> foos = collect( new ArrayList<Foo>(), new ArrayList<Bar>() );or as follows:
List<Foo> foos = collect( new ArrayList<Bar>(), new ArrayList<Foo>() );note that none of the above would have worked if the collect method had been declared as follows:
List<Foo> collect( List<Foo> a1, List<Foo> a2 )