我正在使用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);
}
有人可以澄清以上陈述是否安全,因此可以安全地忽略警告吗?
答案 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);
}