Java:使用两个相关泛型类型声明一个映射(<t> Map <class <?extends =“”classa <t =“”>&gt;,Class <! - ?extends ClassB <T - >&gt;&gt; )</类<?> </T>

时间:2013-01-23 10:05:40

标签: java generics

是否可以声明一个Map,该Map从特定子类的键映射到特定子类的值,但确保两个类共享相同的Type参数?

背景:

ClassA和ClassB都实现了公共资源的行为

public abstract  class ClassA<T> {
      public abstract T getResource() ;
}

public abstract class classB<T> {
       public  abstract void consoumeResource(T resource);
}

我想从ClassA和ClassB的实现映射,并确保只有“兼容”对可以放在一个条目中。

2 个答案:

答案 0 :(得分:5)

另一种方法是提供您自己的Map实施。如果扩展现有实现并使用新类型,则需要的代码不多:

public class CompatibleHashMap<T> extends HashMap<ClassA<T>, ClassB<T>> {

}

现在,CompatibleHashMap<String>只允许您将ClassA<String>作为键,将ClassB<String>作为值。

修改

正如您在评论中提到的那样,您正在将自己与Map实施联系起来。您可以通过执行以下操作来解决此问题:

public class CompatibleMap<T> implements Map<ClassA<T>, ClassB<T>> {

    private Map<ClassA<T>, ClassB<T>> map;

    public CompatibleMap(Map<ClassA<T>, ClassB<T>> map) {
        this.map = map;
    }

    @Override
    public Set<List<T>> keySet() {
        return map.keySet();
    }
    // ... implement all other Map methods by calling the method on map.
}

然后您可以像

一样实例化它
CompatibleMap<String> map = new CompatibleMap<>(new HashMap<ClassA<String>, ClassB<String>>());

这样,您就不依赖于特定的Map实现,如果mapClassAClassB的泛型类型,编译器将抛出错误不一样。

答案 1 :(得分:4)

您无法在地图声明中执行此操作,但可以使用访问/更新地图的方法执行此操作。

e.g。

private final Map<Class, Builder> builderMap = new LinkedHashMap<>();

public <T> void addBuilder(Class<T> tClass, Builder<T> tBuilder) {
     builderMap.put(tClass, tBuilder);
}

public <T> Builder<T> getBuilderFor(Class<T> tClass) {
    @SuppressWarnings("unchecked") 
    Builder<T> tBuilder = (Builder<T>) builderMap.get(tClass);
    return tBuilder;
}