Java泛型中类型参数的前向引用

irr*_*ble 6 java generics

根据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经过改进以放宽排序,同时无论排序如何都能检测循环.

tem*_*def 3

我不确定这是真的。我查看了Java 语言规范,在第 6.3 节中讨论了类型参数的范围:

接口类型参数的范围是接口的整个声明,包括类型参数部分本身。因此,类型参数可以显示为其自身边界的一部分,也可以显示为同一节中声明的其他类型参数的边界。

方法的类型参数的范围是方法的整个声明,包括类型参数部分本身。因此,类型参数可以显示为其自身边界的一部分,也可以显示为同一节中声明的其他类型参数的边界。

构造函数的类型参数的范围是构造函数的整个声明,包括类型参数部分本身。因此,类型参数可以显示为其自身边界的一部分,也可以显示为同一节中声明的其他类型参数的边界。

(我的重点)。

这表明在声明中

B确实在写作时的范围内A extends B

此外,JLS §4.4 指出,当引用类型变量的绑定时,

边界由类型变量、类或接口类型 T组成

这表明它不仅B在 的范围内<A extends B, B>,而且在 上是完全合法的约束A

最后,最重要的是,这段代码编译为javac

public class Test {
     public static <A extends B, B> A test(B obj) {
         return null;
     }
}
Run Code Online (Sandbox Code Playgroud)

所以我非常确定这是完全合法的 Java 代码,并且您链接到的示例要么是错误的,要么是指其他内容。

希望这对您有所帮助,如果我的推理有缺陷,请告诉我!