存储对具有通用类型参数的类的引用及其实现

时间:2018-08-06 14:17:40

标签: java generics

我正在使用Map来存储对泛型类型参数的类和具有相同泛型类型参数的实现对象的引用,

public class SomeImpl<T extends BaseClass> {

    void execute(T instance);
}

现在,在另一个类中,我想基于其通用类型参数存储对实现的引用。

private Map<Class<BaseClass>, SomeImpl<BaseClass>> map;

但是,我发现在这里使用泛型有点令人困惑,尤其是因为显示了很多不安全的强制转换警告。

private <T extends BaseClass> void register(SomeImpl<T> impl, Class<T> aClass) {
    // unsafe
    Class<BaseClass> configClass = (Class<BaseClass>) aClass; 
    // unsafe
    map.put((SomeImpl<BaseClass>) impl, configClass);
}

以及以后我想检索某个实例

private SomeImpl<BaseClass> get(Class<? extends BaseClass> aClass) {
    // unsafe
    return (SomeImpl<BaseClass>) map.get(aClass); 
}

有人可以澄清以上陈述是否安全,因此可以安全地忽略警告吗?

1 个答案:

答案 0 :(得分:0)

最后,我确实采用了以下解决方案。非常感谢Radiodef,他向我指出了类型安全的异构容器的使用。

private Map<Class<?>, SomeImpl<?>> map = new HashMap<>();

以下方法将添加/获取具体实现:

public <T extends BaseClass> void addImpl(SomeImpl<T> loader, Class<T> aClass) {
    map.put(type, loader);
}

public <T extends BaseClass> SomeImpl<T> getImpl(Class<T> aClass) {
    return (SomeImpl<T>) map.get(type);
}

最初,我也在寻找一种可以用任何BaseClass调用的方法。我发现用这种模式是不可能的,所以以下是窍门:

public SomeImpl<BaseClass> getBaseImpl(Class<? extends BaseClass> aClass) {
    return (BaseLoader<BaseClass>) map.get(type);
}

这确实是一个未保存的转换,因为编译器无法确保传递正确类型的BaseClass。但是,我可以确保始终传递正确的类型(或使用isAssignableFrom强制输入)。

这使我可以从数据库中加载一些BaseClass对象,例如:

List<BaseClass> list = getSomeBaseClasses();

Map<Class<? extends BaseClass>, List<BaseClass> map = list.stream()
    .collect(Collectors.groupingBy(BaseClass::getClass));

map.forEach((aClass, bases) -> {
    SomeImpl<BaseClass> impl = getBaseImpl(aClass);
    impls.forEach(impl::execute);
}