Dol*_*000 5 java generics type-erasure
考虑以下Java函数:
public void foo(Class<? extends Exception> cl, List<? extends Exception> ls) throws Exception {
ls.add(cl.newInstance());
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为类型捕获cl并且ls不统一,并且实际上可以指代不同类型.如果编译了这个函数,我本可以称之为foo(NullPointerException.class, new List<SecurityException>()),这本来是非法的.
显然,我们可以通过统一类型捕获来解决这个问题,如下所示:
public <T extends Exception> void foo(Class<T> cl, List<T> ls) throws Exception {
ls.add(cl.newInstance());
}
Run Code Online (Sandbox Code Playgroud)
现在这个功能按预期工作.因此,在我的问题上:有没有办法在单一类型声明中统一类型捕获?
例如,我经常发现自己想要一个将类映射到自己实例的地图.我目前可以想到这样做的唯一方法是有一个伴随的函数来执行未经检查的强制转换:
private Map<Class<? extends Foo>, ? extends Foo> map = ...;
@SuppressWarnings("unchecked")
private <T extends Foo> T getFoo(Class<T> cl) {
return((T)map.get(cl));
}
Run Code Online (Sandbox Code Playgroud)
但是显然更好的是不必禁止警告并让编译器理解地图类型声明中的两种类型捕获应该是相同的,然后只需将地图公开.例如,如果我有一个类似于此的声明:
<T extends Foo> Map<Class<T>, T> map = ...;
Run Code Online (Sandbox Code Playgroud)
显然,这不是有效的语法,但我的问题归结为:是否有任何有效的语法可以让我做一些这样的效果?