Java泛型中的类型参数的前向引用 [英] Forward Reference of Type Parameter in Java Generics

查看:104
本文介绍了Java泛型中的类型参数的前向引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据Java泛型常见问题
http://www.angelikalanger .com / GenericsFAQ / FAQSections / TypeParameters.html#FAQ302
a类型参数不能以这种方式进行前向引用

 < A扩展B,B> //错误

但没关系

 < A extends List< B>,B> // ok 

这两个例子已经过最新的 jdk 1.6.0_24



我的问题是,在语言规范中,这是指定的,隐含的或可扣除的(即如果它不真实,爆炸)。我无法在任何地方找到它。



更新



在javac7中,它被允许。直观地说,类型参数的顺序并不重要;类型系统要求类型变量之间不存在循环依赖关系:< A extends B,B extends A> 。以前,这可以通过禁止前向引用来保证。显然,javac 7被改进以放宽排序,同时检测周期而不管排序如何。 解决方案

我不确定这是否属实。我查看了 Java语言规范并在§ 6.3讨论类型参数的范围:

lockquote

接口的类型参数的范围是接口的整个声明包括类型参数部分本身。因此,类型参数可以作为它们自己的边界的一部分出现,或者作为在同一节中声明的其他类型参数的边界出现。



方法类型的作用域参数是方法的整个声明,包括类型参数部分本身。因此,类型参数可以作为它们自己的边界的一部分出现,也可以作为在同一部分中声明的其他类型参数的边界出现。

构造函数类型的作用域参数是构造函数的整个声明,包括类型参数部分本身。因此,类型参数可以作为它们自己的边界的一部分出现,也可以作为在同一节中声明的其他类型参数的边界出现。


(我强调)。
$ b

这表明在声明中



在写 A extends B 时, B 的确处于范围之内。



另外,JLS的4.4节在提到一个类型变量的边界时指出:


绑定由类型变量或类或接口类型T


组成,这表明不仅是< A extends B,B> 范围内的 B ,而且它是一个完全合法的界限 A



最后,为了解决这个问题,这段代码在 javac

  public class Test {
public static< A extends B,B>测试(B obj){
返回null;


$ / code $ / pre

因此我很确定这是完全合法的Java代码,并且你链接的例子是错误的或者是指的是其他的东西。



希望这有帮助,并让我知道如果我的缺陷推理!


According to Java Generics FAQ http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ302 a type parameter cannot be forward-referenced in this way

<A extends B, B> // error

but it is ok to have

<A extends List<B>, B> // ok

These two examples are verified with the latest jdk 1.6.0_24.

My question is, where in the language spec this is specified, implied, or deductible(i.e. if it is untrue, other things can blow up). I can't find it anywhere.

Update

In javac7, it is allowed. Intuitively, the order of type parameters doesn't matter; the type system requires that there's no cyclic dependencies among type variables: <A extends B, B extends A>. Previously, this can be guaranteed by forbidding forward reference. Apparently javac 7 is improved to relax the ordering, while detecting cycles regardless of ordering.

解决方案

I'm not sure this is true. I looked over the Java Language Specification and in §6.3 there's this discussion of the scopes of type parameters:

The scope of an interface's type parameter is the entire declaration of the interface including the type parameter section itself. Therefore, type parameters can appear as parts of their own bounds, or as bounds of other type parameters declared in the same section.

The scope of a method's type parameter is the entire declaration of the method, including the type parameter section itself. Therefore, type parameters can appear as parts of their own bounds, or as bounds of other type parameters declared in the same section.

The scope of a constructor's type parameter is the entire declaration of the constructor, including the type parameter section itself. Therefore, type parameters can appear as parts of their own bounds, or as bounds of other type parameters declared in the same section.

(My emphasis).

This suggests that in the declaration

that B is indeed in scope when writing A extends B.

Furthermore, §4.4 of the JLS says, when referring to the bound on a type variable, that

The bound consists of either a type variable, or a class or interface type T

Which suggests that not only is B in scope in <A extends B, B>, but that it's a perfectly legal bound on A.

Finally, to top things off, this code compiles in javac:

public class Test {
     public static <A extends B, B> A test(B obj) {
         return null;
     }
}

So I'm pretty sure that this is perfectly legal Java code and that the example you've linked to is either wrong or is referring to something else.

Hope this helps, and let me know if there's a flaw in my reasoning!

这篇关于Java泛型中的类型参数的前向引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆