如何使用其键和值属于某个层次结构的通用映射?

Sou*_*sak 3 java generics map

我的目标是创建一个Map,其键是Class实例,其值是相应Class的实例.含义,

Map(层次结构中的某个类 - >其对应的实例)

为此,我宣布Map为

Map<Class<? extends BaseService>, ? extends BaseService> serviceMap = 
    new HashMap<Class<? extends BaseService>, BaseService>();
//Assume BaseService is at the root of hierarchy.
Run Code Online (Sandbox Code Playgroud)

以上编译.

为了填充Map,我使用了

public <T extends BaseService> void register(T service) {   
    serviceMap.put(service.getClass(), service);    
}
Run Code Online (Sandbox Code Playgroud)

这不编译.

我该如何工作?为什么不编译?

And*_*yle 5

您对通配符的使用与您的英语定义不完全一致.当你定义:

Map<Class<? extends BaseService>, ? extends BaseService> serviceMap;
Run Code Online (Sandbox Code Playgroud)

这可能被描述为" serviceMap是从类扩展BaseService某种类型的值(它是BaseService或子类)" 的映射.

编译器register在此上下文中拒绝您的方法是正确的. serviceMap声明的值类型只是"某种东西" - 因此您可以轻松地为其指定值,类型为ServiceImplOne.并且可以使用类的参数调用您的register方法ServiceImplTwo.您无法将其插入到地图中,因为它与通用参数不一致!

很明显,由于您希望能够插入任何类型的服务,因此映射必须接受所有BaseService as值的实例,而不是BaseService的某些(未知)子类型.因此,您可以通过使用具体值类型声明地图来解决此问题:

Map<Class<? extends BaseService>, BaseService> serviceMap;
Run Code Online (Sandbox Code Playgroud)