0

I've been for ages trying to figure out what's on earth the difference between a List<? extends A> and a List<A>.

What can I do, what couldn't I do...?

Jordi
  • 15,016
  • 25
  • 94
  • 208
  • 2
    Possible duplicate of [Difference between super T> and extends T> in Java](http://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java) – user3707125 Feb 01 '16 at 11:43

2 Answers2

2

A List<? extends A> reference will allow its value to be a List of A or any child / implementing class.

For instance, with parent class A and child B, the following idiom is valid:

List<? extends A> list = new ArrayList<B>();

... whereas List<A> list = new ArrayList<B>(); wouldn't compile.

However

A bounded type parameter with wildcards (the <? extends A> idiom) comes at a cost.

You cannot add elements to the List, only remove elements, iterate it or query its contents.

That is because the specific type of elements in your list will be unknown at runtime, hence adding any element is unsafe.

Mena
  • 45,491
  • 11
  • 81
  • 98
1

If you have class B extends A then

You can do:

List<? extends A> myList = new ArrayList<B>();

because List<? extends A> is a list whose generic type is some subtype of A. Therefore you cannot safely put anything into List<? extends A> because you don't know how specific its generic type actually is. You only know that the items it contains must be A, so you can take A out of it.

You cannot do:

List<A> myList = new ArrayList<B>();

because List<A> is a list whose generic type is A.

Therefore if you have a List<A> you know that its generic type is exactly A, so you can put any instance of A into it.

khelwood
  • 46,621
  • 12
  • 59
  • 83