【发布时间】:2015-04-15 20:58:59
【问题描述】:
这是一个简单的示例,演示了我遇到的与类型擦除相关的问题。我有这样的课:
public abstract class AbstractHandler<T> {
...
public abstract Class<T> handledType();
}
然后我有这个实现:
public class ConcreteHandler extends AbstractHandler<Map<String, List<Thing>>> {
@Override
public Class<Map<String, List<Thing>>> handledType() {
//what do I return here?!
}
}
我无法返回Map<String, List<Thing>>.class,因为这在语法上甚至都无效。我尝试将子类型中的泛型类型参数设为HashMap<String, List<Thing>>,然后返回new HashMap<String, List<Thing>>().getClass(),但这不起作用,因为Class<T>#getClass() 的返回类型是Class<? extends T>。我从 Guava 中查看了 TypeToken,getRawType 方法看起来很有希望,但它返回 Class<? super T>。
我暂时有一个解决方法,如下所示:
public class ThingListMap {
private Map<String, List<Thing>> thingListMap;
...
}
我只是使用ThingListMap 作为通用类型参数。
另一种可能的解决方法是执行强制转换:
public Class<Map<String, List<Thing>>> handledType() {
return (Class<Map<String, List<Thing>>>) new HashMap<String, List<Thing>>().getClass();
}
有没有更优雅的方式来做到这一点?
编辑:针对其中一个答案,我无法更改 handledType 方法的签名,因为我不拥有或控制其来源。
【问题讨论】:
-
需要更多关于该方法的目的的信息
-
有没有办法做到这一点?" 在纯 Java 中,没有。
-
@eduyayo 这更像是一个概念性问题。我确实有一个解决方法,但我想看看是否有更优雅的方法。
-
你的课设计得不好。
java.lang.Class类的实例代表类(废话),但您正试图使用一个来代表 type,这是更通用的东西。 Java 确实有一个用于此概念的Type类,但它可能也无法满足您的目的。 -
@JohnBollinger 我完全同意,但我没有设计这个类,所以我不能改变它。 :(
标签: java generics type-erasure generic-type-argument