Reputation: 96391
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
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
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
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