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

时间:2011-03-05 04:31:11

标签: java generics

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

2 个答案:

答案 0 :(得分:3)

我不确定这是真的。我查看了Java Language Specification,然后在§6.3中讨论了类型参数的范围:

  

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

     

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

     

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

(我的重点)。

这表明在声明中

撰写BA 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时你会怎么说?