Reputation: 277
A book I am reading on Java tells me that the following two pieces of code are equivalent:
public <T extends Animal> void takeThing(ArrayList<T> list)
public void takeThing(ArrayList<? extends Animal> list);
On the opposite page, I am informed that the latter piece of code uses the '?' as a wildcard, meaning that nothing can be added to the list.
Does this mean that if I ever have a list (or other collection types?) that I can't make them simultaneously accept polymorphic arguments AND be re-sizable? Or have I simply misunderstood something?
All help/comments appreciated, even if they go slightly off topic. Thanks.
Upvotes: 5
Views: 859
Reputation: 200296
Usually, if adding to a list is involved inside a method that accepts just the list without the thing to add, you'll have somewhere else something that is an Animal
and you'll want to add it to the list. In this case your method must be declared so that all the list types it accepts allow adding an Animal
into them. This will have to be a List<Animal>
or a list of some supertype of Animal
. It can't possibly be a List<Dog>
— the element you are adding could be any Animal
.
This is where the concept of the lower bound, and the keyword super
, come in. The type declaration List<? super Animal>
matches all the acceptable types as described above. On the other hand, you won't be able to get elements out of such a list in a typesafe way because they can in general be of any type at all. If a method wants to both add and get elements of declared type Animal
, the only valid type it can accept is a List<Animal>
.
Upvotes: 1
Reputation: 207006
Does this mean that if I ever have a list (or other collection types?) that I can't make them simultaneously accept polymorphic arguments AND be re-sizable?
No.
The two pieces of code are not completely equivalent. In the first line, the method takeThing
has a type parameter T
. In the second line, you're using a wildcard.
When you would use the first version, you would specify what concrete type would be used for T
. Because the concrete type is then known, there's no problem to add to the list.
In the second version, you're just saying "list
is an ArrayList
that contains objects of some unknown type that extends Animal
". What exactly that type is, isn't known. You can't add objects to such a list because the compiler doesn't have enough information (it doesn't know what the actual type is) to check if what you're adding to the list should be allowed.
Upvotes: 3