根据Java Generics FAQ http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ302 ,类型参数不能以这种方式前向引用
<A extends B, B> // error
Run Code Online (Sandbox Code Playgroud)
但是没关系
<A extends List<B>, B> // ok
Run Code Online (Sandbox Code Playgroud)
这两个例子用最新的验证jdk 1.6.0_24.
我的问题是,在语言规范中,这是指定的,隐含的还是可扣除的(即如果它是不真实的,其他事情可能会爆炸).我找不到任何地方.
更新
在javac7中,它是允许的.直观地说,类型参数的顺序无关紧要; 类型系统要求类型变量之间没有循环依赖关系:<A extends B, B extends A>.以前,这可以通过禁止前向参考来保证.显然,javac 7经过改进以放宽排序,同时无论排序如何都能检测循环.
首先,一点背景(如果不感兴趣,可以跳过一点).我很生气,很困惑!这应该是一个非常简单的用例,事实上我的代码已经用Eclipse JDT编译器编译得很好,所以直到现在我一直在配置Maven以确保这样做.尽管它不能用Oracle JDK和OpenJDK编译,但是我一直在困扰我,因为我认为它可能实际上是我的代码的问题,所以我再次研究它.
我想也许这个bug是在JDT编译器中允许它编译的,而不是Oracle JDK和OpenJDK因为不允许它,我也用它来测试这两个.有问题的原始代码要复杂得多,所以我很难看到问题出在哪里,事实上,我很惊讶地发现在不编译的情况下可以减少这个问题的程度.
Eclipse JDT编译器或Oracle JDK和OpenJDK都有一个非常重要的(imho)错误.
这是相关代码的相当小的表示.(Anything的类型绑定可以被任何接口替换,编译器行为不会改变):
public class Bug<X extends Property<?, ?> & Anything> {
}
interface Property<C, S extends C> extends PropertyConst<C> {
@Override
public S get();
}
interface PropertyConst<C> {
public C get();
}
interface Anything {
}
Run Code Online (Sandbox Code Playgroud)
总而言之,我认为这应该编译得很好,但Oracle JDK 7&8和OpenJDK 7不同意.它使用Eclipse Juno为我编译.
当使用这些编译器中的任何一个编译时,上面的代码给出类似于以下错误的东西,但是对于JDT编译器工作得很好:
Bug.java:3: error: types PropertyConst<?> and Property<?,?> are incompatible; both define get(), but with unrelated return types
public class Bug<X extends Property<?, ?> & Anything> {
^
1 …Run Code Online (Sandbox Code Playgroud)