My objective is to create a Map whose keys are Class instances and whose values are instances of the corresponding Class. Meaning,
Map (a certain class in a hierarchy --> its corresponding instance)
To do that, I declared Map like
Map<Class<? extends BaseService>, ? extends BaseService> serviceMap =
new HashMap<Class<? extends BaseService>, BaseService>();
//Assume BaseService is at the root of hierarchy.
The above compiles.
In order to populate the Map, I used
public <T extends BaseService> void register(T service) {
serviceMap.put(service.getClass(), service);
}
This does not compile.
How do I make this work ? And why doesn't this compile ?
Your use of wildcards isn't exactly consistent with your English definition. When you define:
Map<Class<? extends BaseService>, ? extends BaseService> serviceMap;
this might be described as "serviceMap
is a map from Classes which extend BaseService
, to some type of value (which is BaseService
or a subclass)".
The compiler is correct to reject your register
method in this context. serviceMap
's value type is declared to be simply "something" - so you could easily assign a map to it with a value type of ServiceImplOne
. And your register method could be called with an argument of class ServiceImplTwo
. You can't insert this into the map as it's not consistent with the generic parameters!
It's clear that since you want to be able to insert any type of service, the map must accept all instances of BaseService
as values, not some (unknown) subtype of BaseService. Therefore you can fix this by declaring the map with a concrete value type:
Map<Class<? extends BaseService>, BaseService> serviceMap;