James Raitsev
James Raitsev

Reputation: 96391

Adding elements to List<? extends Superclass>, clarification needed

If A extends X, the following declaration is valid

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

It seems to be that a list would hold a collection of elements that extend X. As such, new A() should qualify.

Yes, it does not. Why is that?

Upvotes: 1

Views: 1068

Answers (3)

Daniel Pryden
Daniel Pryden

Reputation: 60947

You've almost got it. List<? extends X> means "a list of some type (which I don't actually know) which is a subtype of X (or possibly X itself)".

The problem is if X is, for example, Number. Then List<? extends X> means List<Double> or List<Integer> or some other type, which you've just said you don't actually know. You can't insert any Number into a List<Integer>. So, since you don't know the type of the elements of the list, you can't insert anything into a List<? extends Number>. You can, however, retrieve values from the list, and you are guaranteed that any value contained in the list is at least a Number.

For more information, read Item 28: Use bounded wildcards to increase API flexibility in Effective Java, 2nd Ed. by Joshua Bloch (a book which every Java programmer should have on their bookshelf). In particular, this item explains the mnemonic PECS, meaning "producer extends, consumer super", which will help you remember what the extends and super keywords mean in Java generics and when they should be used.

Upvotes: 5

devang
devang

Reputation: 5516

You are creating a list reference (variable) that is generics extends type. This indicates that the list can hold instances of classes that have X as superclass. However, when creating actual instance of the list, you restrict it to hold instances of only class A. Doesn't that sound odd?

Upvotes: 0

Marko Topolnik
Marko Topolnik

Reputation: 200148

List<? extends X> is no definite type. It means that the variable list can be assigned from a range of types, such as List<A>, but also List<B> (where B extends X). If the compiler allowed you to add new A() to such a list, you would be adding an A to List<B>. That would be a failure of type safety.

Upvotes: 2

Related Questions