返回具有泛型类型的Class实例

Viv*_*ath 12 java generics generic-type-argument type-erasure

这是一个简单的示例,演示了我遇到的与类型擦除相关的问题.我有一个这样的课:

public abstract class AbstractHandler<T> {

    ...
    public abstract Class<T> handledType();
}
Run Code Online (Sandbox Code Playgroud)

然后我有这个实现:

public class ConcreteHandler extends AbstractHandler<Map<String, List<Thing>>> {

    @Override
    public Class<Map<String, List<Thing>>> handledType() {
        //what do I return here?!
    }
}
Run Code Online (Sandbox Code Playgroud)

我不能回来Map<String, List<Thing>>.class,因为那在语法上甚至都没有.我尝试在子类型中创建泛型类型参数HashMap<String, List<Thing>>然后返回new HashMap<String, List<Thing>>().getClass(),但这不起作用,因为返回类型Class<T>#getClass()Class<? extends T>.我TypeToken从Guava 看了一下,这个getRawType方法似乎很有希望,但它又回来了Class<? super T>.

我现在有一个解决方法,看起来像这样:

public class ThingListMap {
    private Map<String, List<Thing>> thingListMap;

    ...
}
Run Code Online (Sandbox Code Playgroud)

我只是ThingListMap用作泛型类型参数.

另一种可能的解决方法是执行强制转换:

public Class<Map<String, List<Thing>>> handledType() {
    return (Class<Map<String, List<Thing>>>) new HashMap<String, List<Thing>>().getClass();
}
Run Code Online (Sandbox Code Playgroud)

有更优雅的方式吗?

编辑:为了回答其中一个答案,我无法更改handledType方法的签名,因为我不拥有或控制其来源.

rge*_*man 7

出于某种原因,Java不允许您Map.class直接转换为Class<Map<String, List<Thing>>>.无论如何,这是一个未经检查的演员.

但是把它投两次是合法的,首先是Class<?>,然后是Class<Map<String, List<Thing>>>.

return (Class<Map<String, List<Thing>>>) (Class<?>) Map.class;
Run Code Online (Sandbox Code Playgroud)

作为未经检查的演员,您可能想要添加@SuppressWarnings("unchecked").

  • *"出于某种原因[...]"**基本上同样的原因你不能将`List <Cat>`强加给`List <Dog>`.也不是另一个的超类型或子类型.另请参阅[*"无法从列表<列表>转换为列表<列表<?>>"*](http://stackoverflow.com/q/26766704/2891664).RE:这里的答案是,对于像对象创建这样的东西来说,转换很好但是请注意,例如`Class <Map <String,String >>`将`==``Class <Map <Integer,Integer >> . (2认同)
  • @Radiodef是的,这就是原因.感谢您指出了这一点. (2认同)