我的目标是创建一个Map,其键是Class实例,其值是相应Class的实例。含义,
Map(层次结构中的某个类 - >其对应的实例)
为此,我宣布了地图
Map<Class<? extends BaseService>, ? extends BaseService> serviceMap =
new HashMap<Class<? extends BaseService>, BaseService>();
//Assume BaseService is at the root of hierarchy.
以上编译。
为了填充地图,我使用了
public <T extends BaseService> void register(T service) {
serviceMap.put(service.getClass(), service);
}
这不编译。
如何使这项工作?为什么不编译?
答案 0 :(得分:5)
您对通配符的使用与您的英语定义不完全一致。定义时:
Map<Class<? extends BaseService>, ? extends BaseService> serviceMap;
这可能被描述为“serviceMap
是一个来自类的地图,它将BaseService
扩展为某些类型的值(即BaseService
或子类)”。
在此上下文中,编译器拒绝您的register
方法是正确的。 serviceMap
的值类型被声明为“某种东西” - 因此您可以使用值类型ServiceImplOne
轻松地为其分配地图。并且可以使用类ServiceImplTwo
的参数调用您的register方法。您无法将其插入到地图中,因为它与通用参数不一致!
很明显,由于您希望能够插入任何类型的服务,因此地图必须接受 BaseService
的所有实例作为值,而不是某些 (未知)BaseService的子类型。因此,您可以通过使用具体值类型声明地图来解决此问题:
Map<Class<? extends BaseService>, BaseService> serviceMap;