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

时间:2012-07-30 10:56:31

标签: java generics map

我的目标是创建一个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);    
}

这不编译。

如何使这项工作?为什么不编译?

1 个答案:

答案 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;