使用Class作为键和具有在关键类实例上操作的对象的值进行映射

时间:2013-08-09 22:21:33

标签: java generics

我对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中使用吗?

2 个答案:

答案 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