将类映射到其参数与类的参数相同的泛型

时间:2014-03-02 02:24:53

标签: java generics collections

我的情况是需要这样的地图:

Map<Class<T>, SomeGeneric<T>>

包含此地图的类不能是通用的。到目前为止我所拥有的是:

private class Factory {
    Map<Class<? extends Base>, TypedFactory<? extends Base>> map;

    public Factory() {
        map = new HashMap<Class<? extends Base>, TypedFactory<? extends Base>>();
    }

    public <T extends Base> T get(Class<T> clazz, String id) {
        TypedFactory<T> factory = map.get(clazz);

        if (factory == null) {
            factory = new TypedFactory<T>();
            map.put(clazz, factory);
        }

        return factory.get(id);
    }

    private class TypedFactory<T extends Base> {
        Map<String, T> typeMap;

        public TypedFactory() {
            typeMap = new HashMap<String, T>();
        }

        public T get(String id) {
            return typeMap.get(id);
        }
    }

    private class Base {

    }
}

当我尝试编译时,我收到此错误:

error: incompatible types
            TypedFactory<T> factory = map.get(clazz);
                                             ^
  required: Factory.TypedFactory<T>
  found:    Factory.TypedFactory<CAP#1>
  where T is a type-variable:
    T extends Factory.Base declared in method <T>get(Class<T>,String)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Factory.Base from capture of ? extends Factory.Base
1 error

Java的类型系统是否足以处理这个用例,或者我是SOL?

1 个答案:

答案 0 :(得分:4)

Java的类型系统不够强大,无法证明您的特定设计模式实际上是类型安全的 - 所以如果不抛弃一个丑陋的@SuppressWarnings("unchecked")或两个,你将无法做到这一点,但是你可以做到。

只需改变:

TypedFactory<T> factory = map.get(clazz);

要:

TypedFactory<T> factory = (TypedFactory<T>) map.get(clazz);

由于您的Factory类控制TypedFactory个实例的实例化和存储,因此该地图可以证明是类型安全的,所以你很好;只是Java编译器不够聪明才能识别出来。

相关问题