Why do I get a compile time error on this piece of code?
public Interface Location {
.......
}
Class code...
Map<Type, List<? extends Location>> locationsTypeMap = new HashMap<Type, List<? extends Location>>();
/**
Code to add elements to the hashMap.
*/
newLocation = getNewLocation()
while(mapHasElements){
Location.Type key = location.getType();
List<? extends Location> valueList = (List<? extends Location>)locationsTypeMap.get(key); //1
valueList.add(newLocation);/*Compile error*/
}
On the other hand, if I replace step 1 with line below it works
List<Location> valueList = (List<Location>)locationsTypeMap.get(key);
The wildcard "? extends Location" means "I want it to be List<T>
for some T
where T
is a subclass of Location
(or is Location
itself)."
Now, let's leave that to one side for a second. Would you expect this to compile:
List<String> strings = new List<String>();
strings.add(new Object());
? I wouldn't think so - you can't add a bare "object" to a list of strings. Any item in a list of strings has to be a string.
Go back to your first thing. Suppose locationsTypeMap.get(key)
returns an object which is (logically - ignore type erasure for now) a List<ExoticLocation>
- but suppose newLocation is actually an instance of BoringLocation
. You shouldn't be able to add a BoringLocation
to a List<ExoticLocation>
and the compiler knows that - so it stops that from happening.
Anything you get from a List<? extends Location>
is guaranteed to be a Location
of some kind... but you can't add anything to it. The reverse is true with super
: you can't guarantee that anything you get from a List<? super Location>
will be a Location
, but you can add a Location
to it.
To give a very different example: is a bunch of bananas a collection of fruit? Well it is in one sense - anything you get from it is a fruit. But it's not in another, because you can't add any old kind of fruit to it - if you try to add an apple, it'll fall off :)
See Angelika Langer's Java Generics FAQ for a lot more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With