有问题的代码如下所示。
class GenericClass<T> {
// ...
}
class RegisterHandler<T> {
// ...
public void register( Class<T> klazz ) {
// do something
}
// ...
}
class GenericClassRegisterHandler extends RegisterHandler<GenericClass<?>> {
// ...
}
public static void registerAll() {
// ...
new GenericClassRegisterHandler().register( GenericClass.class );
// error: actual argument Class<GenericClass> cannot be converted to Class<GenericClass<?>> by method invocation conversion
// ...
}
唯一的方法是使用rawtypes,方法是将register
改为Class klazz
而不是Class<T>
,或者将new GenericClassRegisterHandler()
转换为(RegisterHandler)new GenericClassRegisterHandler()
。由于这两个“修复”都利用了原型并且我不想使用它们(我为什么要这样做?我应该能够Class<GenericClass<?>>
以某种方式得到.class
!),但我看不到其他解决方案至今。我是否遗漏了一些显而易见的东西,而且可能没有重新包装等等,或者它只是不可能?
注意:Wrapping a Class<?> type generics error是一个很好的&amp;启发查找,但在这里不起作用。
注2:虽然EJ 2nd中的Bloch正在讨论类似问题,但我无法找到任何明确的解决方案。
由于(Class<GenericClass<?>>) GenericClass.class
incompatible types: Class<GenericClass<?>> cannot be converted to Class<GenericClass>
无效
上的测试代码段
答案 0 :(得分:1)
这项任务可以通过小修改来解决:
static class RegisterHandler<T> {
public <E extends T> void register( Class<E> klazz ) { // <== Note additional generics customization.
// do something
}
}
同意,泛型有点棘手=)
答案 1 :(得分:0)
我的解决方案是进行双重演员。
new GenericClassRegisterHandler()
.register( (Class<GenericClass<?>>) (Class<?>) GenericClass.class );
虽然它可能不是最优雅的,但在某些情况下(例如,您是制作人,消费者的界面是一成不变的,或者您只是不喜欢想要因任何其他原因而改变它)它是最好的 - 因为它是唯一可能的。
答案 2 :(得分:-1)
怎么样
class GenericClassRegisterHandler extends RegisterHandler<GenericClass>
?
我知道,你说,你不想使用“原始”类型,但GenericClass<?>
不再是“原始”,而是GenericClass用于所有意图和目的。