我对Java Generics有一个问题,我不确定它是否可能是我想要的。基本上标题说了这一切,但让我举个例子。目前我有这样的事情:
private static Map<Class<? extends Exception>, ExceptionTranslator<?>> MAP;
以下列方式使用:
MAP.put(SomeException.class, new ExceptionTranslator<SomeException>());
但我想强制执行作为键传递的异常类型的翻译器,类似于你在方法上所做的事情:
<T extends Exception> Map<Class<T>, ExceptionTranslator<T>> MAP;
这当然不是一个正确的代码,我想我的generics-foo不够强大。它甚至可以在Java中使用吗?
答案 0 :(得分:2)
我只想解释为什么不可能。
问题在于无法保证类型安全。 Map依赖于equals / hashMap,编译器无法证明这些方法与T类型的正确性。
想象一下,如果代替Class
,你将使用自己的泛型类,它将为其所有实例返回equals == true。在这种情况下,您可以将一种类型放入地图中,但是使用另一种类型进行提取,它将生成强制转换异常:
private<E extends Number> void mp()
{
Map<Key<E>, E> map = new HashMap<>();
map.put(new Key<Integer>(), 42);// Yes, there is compilation error!
// Otherwise we could do this:
String str = map.get(new Key<String>());// cast exception!
}
class Key<T>
{
@Override
public int hashCode()
{
return 0;
}
@Override
public boolean equals(final Object obj)
{
return obj instanceof Key;
}
}
答案 1 :(得分:0)
你不能只用普通的地图做到这一点;你必须使用强制类型约束的方法进行自己的包装。请参阅相关问题Java generics enforce same type for keys and values of map。