2

我对 Java 泛型有疑问,我不确定它是否可能是我想要得到的。基本上标题说明了一切,但让我举个例子。目前我有这样的事情:

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中甚至可能吗?

4

2 回答 2

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;
    }
}
于 2013-08-09T23:15:45.700 回答
0

您不能仅使用普通地图来做到这一点;您必须使用强制类型约束的方法进行自己的包装。请参阅相关问题Java 泛型对 map 的键和值强制执行相同类型

于 2013-08-09T23:07:31.360 回答