根据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经过改进以放宽排序,同时无论排序如何都能检测循环.
我不确定这是真的。我查看了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 代码,并且您链接到的示例要么是错误的,要么是指其他内容。
希望这对您有所帮助,如果我的推理有缺陷,请告诉我!