我现在的情况是,我想要一个映射,其中键是接口(interface)类,相应的值是实现该接口(interface)的类。换句话说,键和值类型是相关的。
我当前的添加到 map 并获取实现类实例的方法的实现如下所示:
// should be something like Class<T>, Class<? extends T>
static Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>> ();
public static <T> void add(Class<T> interfaceT,
Class<? extends T> implementationT) {
map.put(interfaceT, implementationT);
}
public static <T> T get(Class<T> interfaceT) {
// cast caused by definition not complete.
Class<T> implementationT = (Class<T>) map.get(interfaceT);
// try catch stuff omitted
T t = implementationT.newInstance();
return t;
}
我的问题是:
我可以定义“map”变量,这样就不需要 get(...) 方法中的强制转换吗?我无法使“new HashMap<Class<T>, Class<? extends T>>
()' 工作,所以要么它是不可能的,要么我错过了一些基本的东西:)
请指教:)
编辑:事实证明 Class 上的 asSubclass() 方法做了我想要的事情:D
Class<?> rawClassFromMap = map.get(interfaceT);
Class<? extends T> implementationT = rawClassFromMap.asSubclass(interfaceT);
implementationT 的类型是“? extends T”就可以了,因为我只需要返回一个 T 对象。
我喜欢泛型。让我想起了 Haskell...
最佳答案
看起来目标类似于 Josh Bloch 在 Chapter 5 of Effective Java (item 29). 中描述的“类型安全异构容器”在他的例子中,他将类型( Class<T>
)映射到(已实例化的)实例( T
)。
您可以使用 asSubclass
执行类似的操作而不是cast
:
final class Factory
{
private Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
<T> void map(Class<T> type, Class<? extends T> impl)
{
map.put(type, impl.asSubclass(type));
}
private <T> Class<? extends T> get(Class<T> type)
{
Class<?> impl = map.get(type);
if (impl == null)
throw new IllegalArgumentException("Unknown type: " + type);
return impl.asSubclass(type);
}
<T> T create(Class<T> type)
throws Exception
{
Class<? extends T> impl = get(type);
Constructor<? extends T> ctor = impl.getConstructor();
return ctor.newInstance();
}
}
关于java - 泛型可以允许 Java 编译器检查映射中键和值的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1473444/