java泛型范围_Java泛型类型中的通配符参数在其范围内的正式条件是什么?

允许使用不相关接口类型的? extends通配符:Foo extends Runnable>有效

不允许使用不相关类类型的? extends通配符:Foo extends Thread>无效。这是有意义的,因为没有类型可以同时是Number和Thread的子类型。

在? super通配符中,通配符中的下界必须是类型变量绑定的子类型:不允许Foo super Runnable>,因为Runnable不是Number的子类型。同样,这种限制是完全合理的。

小精灵

但是这些规则是在哪里定义的呢?查看Java语言规范第4.5部分,我没有看到任何区别于类的接口,并且当应用我对JLS EDCOX1的解释时,7表示是有效的。所以我可能误解了一些事情。这是我的尝试:

从JLS的该部分:

A parameterized type consists of a class or interface name C and an actual type argument list . It is a compile time error if C is not the name of a generic class or interface, or if the number of type arguments in the actual type argument list differs from the number of declared type parameters of C. In the following, whenever we speak of a class or interface type, we include the generic version as well, unless explicitly excluded. Throughout this section, let A1 , ... , An be the formal type parameters of C, and let be Bi be the declared bound of Ai. The notation [Ai := Ti] denotes substitution of the type variable Ai with the type Ti, for 1 <= i <= n, and is used throughout this specification.

Let P = Gbe a parameterized type. It must be the case that, after P is subjected to capture conversion (§5.1.10) resulting in the type G, for each actual type argument Xi, 1 <= i <= n , Xi

将其应用于p=Foo super Runnable>:即c=Foo,n=1,t1=? super Runnable,b1=Number。

对于捕获转换,此部分捕获转换定义适用:

If Ti is a wildcard type argument of the form ? super Bi, then Si is a fresh type variable whose upper bound is Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.

给出了g=Foo,其中X是一个具有上界Number和下界Runnable的新类型变量。我没有看到任何明确禁止使用这种类型变量的内容。

b1=Number中没有类型变量,所以bi[a1:=x1,…,an:=xn]仍然只是Number而已。X使用Number作为上界(来自捕获转换),根据子类型规则"类型变量的直接超类型是其界中列出的类型",因此X小于:Number(=bi[a1:=x1,…,an:=xn]),因此该参数在其界内。(但事实并非如此!)

按照相同的推理,每个通配符都在其边界内,因此这里的某些内容不正确…但这种推理到底哪里出错了呢?这些规则在正确应用时如何工作?

关于泛型的jls是不完整的,您在其中发现了另一个漏洞。关于类型变量的下界几乎没有讨论过,我在规范中也没有看到对具有上界Number和下界Runnable的X的任何限制。他们可能忘了。

直观地说,必须至少有一个可能的类型同时满足类型变量的上界和下界,否则该变量和所有使用该变量的类型都将是无用的。因为这几乎肯定是一个编程错误,所以编译应该失败。

很容易检查上界和下界是否构成空的类型集。所有下界的超类型都是已知的;它们中至少有一个应该是上界,否则两个边界内没有类型。

——

两个Foo extends A>案例在规范中有很好的定义,通过捕获转换,我们有了新的类型变量X和上界A & Number,规范中说是上界V1&...&Vm。

It is a compile-time error if for any two classes (not interfaces) Vi and Vj,Vi is not a subclass of Vj or vice versa.

因此,如果A=线程,则捕获转换失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值