的类型
ShapeSaver.class是
Class<ShapeSaver>。当将其提供给时
genericsHell(),编译器需要检查是否
Class<ShapeSaver>为的子类型
Class<?extendsShapeProcessor<?>,这将简化为是否
ShapeSaver为的子类型
ShapeProcessor<?>。子类型关系不成立,方法调用失败。
@Bohemian的解决方案也应如此。在此,子类型检查在推断出
T之后的边界检查时发生
T。它也应该失败。这似乎是一个编译器错误,它以某种方式曲解了
Raw可分配给的规则,就
Raw<X>好像
Raw是的子类型一样
Raw<X>。
一个简单的解决方案是声明
void genericsHell(Class<? extends ShapeProcessor> a)
确实
ShapeSaver是的子类型
ShapeProcessor,并且该调用会编译。
这不只是一种解决方法。有充分的理由。严格来说,对于任何
Class<X>,都
X必须是原始类型。例如,
Class<List>可以,
Class<List<String>>不能。因为确实没有代表的阶级
List<string>;
只有一个类代表
List。
忽略将不使用原始类型的严厉警告。给定Java类型系统的设计方式,有时我们必须使用原始类型。甚至Java的核心API(
Object.getClass())都使用原始类型。
您可能打算这样做
genericsHell(ShapeSaver<Circle>.class);
不幸的是,这是不允许的。Java可以但没有引入类型文字和泛型。这给很多图书馆带来了很多问题。
java.lang.reflect.Type一团糟,无法使用。每个库都必须引入自己的类型系统表示法来解决该问题。
您可以向Guice借钱,例如
genericsHell( new TypeLiteral< ShapeSaver<Circle> >(){} ) ------------------(学习
ShaveSaver<Circle>在阅读代码时跳过胡扯)
在的方法主体中
genericsHell(),您将拥有完整的类型信息,而不仅仅是类。



