根据Java Generics常见问题解答 http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ302 类型参数不能以这种方式正向引用
<A extends B, B> // error
但是可以
<A extends List<B>, B> // ok
使用最新的jdk 1.6.0_24
验证了这两个示例。
我的问题是,在语言规范中,这是指定的,隐含的还是可扣除的(即,如果它是不真实的,其他事情可能会爆炸)。我无法在任何地方找到它。
更新
在javac7中,它是允许的。直观地说,类型参数的顺序无关紧要;类型系统要求类型变量之间没有循环依赖关系:<A extends B, B extends A>
。以前,这可以通过禁止前向参考来保证。显然javac 7经过改进以放松排序,同时无论排序如何都能检测循环。
答案 0 :(得分:3)
我不确定这是真的。我查看了Java Language Specification,然后在§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;
}
}
中编译:
{{1}}
所以我很确定这是完全合法的Java代码,你链接到的例子是错误的或是指其他东西。
希望这有帮助,如果我的推理存在缺陷,请告诉我!
答案 1 :(得分:0)
这是完全合法的,更多,你可以想象A扩展C,这通常是扩展B. 那么当C扩展B时你会怎么说?