为什么这些泛型不能在OpenJDK7中编译,而是在OpenJDK6中编译

Dzm*_*rka 8 java generics openjdk nested-generics

class HasId<I> {}
class HasStringId extends HasId<String> {}
class Alert<T extends /*Some*/Object> extends HasStringId {}
class BaseController<M extends HasId<String>> {
    // abstract Class<M> getModelClass();
}
class AlertController extends BaseController<Alert> { // error here
    // @Override Class<Alert> getModelClass() {
    //     return Alert.class;
    // }
}
Run Code Online (Sandbox Code Playgroud)

在OpenJDK6上编译很好,但在OpenJDK7中给出:

AlertController.java:50: error: type argument Alert is not within bounds of
    type-variable T
class AlertController extends BaseController<Alert> {
                                        ^
  where T is a type-variable:
    T extends HasId<String> declared in class BaseController
Run Code Online (Sandbox Code Playgroud)

请注意,第50行有rawtype警告,因为必须参数化Alert.如果我这样做,例如extends BaseController<Alert<Object>>代码编译.但我不能这样做,因为我需要实现getModelClass().

更新:这是Java 6实现中的一个错误,已在Java 7中修复:http://bugs.sun.com/bugdatabase/view_bug.do?video_id = 6559182.(这是我对编译器开发者的问题:http://openjdk.5641.n7.nabble.com/Nested-generics-don-t-compile-in-1-7-0-15-but-do-in-1 -6-0-27-td121820.html)

Pau*_*ora 1

有许多记录在案的案例表明,对于各种泛型细微差别,Java 7 编译器比 Java 6 编译器更严格。这些情况通常与变得更加具体的实际语言规范有关。该错误可能与使用任何原始类型有关,本质上是“选择退出”继承类型上的泛型 - 但它是否正确是有争议的。

编辑:我在JDK 7 不兼容列表中找不到这个问题。该错误可以使用 sun-jdk-1.7.0_10重现,但不能使用 Eclipse 编译器重现(在涉及泛型细微差别时,Eclipse 历史上比 javac 具有更好的跟踪记录)。您应该提交 Oracle 错误。

这是一个可能的解决方法:

class AlertController extends BaseController<Alert<?>> {
    @Override
    @SuppressWarnings("unchecked")
    Class<Alert<?>> getModelClass() {
        return (Class<Alert<?>>)(Class<?>)Alert.class;
    }
}
Run Code Online (Sandbox Code Playgroud)