gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-30 21:33:12 26 4
gpt4 key购买 nike

对于 Java 中的参数化类型,检查参数是否在其绑定(bind)范围内的规则如何完全通配符?

给定这样一个类:

class Foo<T extends Number> {}

对编译器接受的内容进行试验了解到:

  • A ? extends允许使用不相关接口(interface)类型的通配符:Foo<? extends Runnable>有效
  • A ? extends不允许使用不相关类类型的通配符:Foo<? extends Thread>是无效的。这是有道理的,因为没有类型可以同时是 Number 的子类型。和 Thread
  • ? super通配符,通配​​符中的下界必须是类型变量边界的子类型:Foo<? super Runnable>不允许,因为 Runnable不是 Number 的子类型.同样,这个限制非常有意义。

但是这些规则是在哪里定义的呢?看着 Java Language Specification section 4.5 ,我没有看到任何区分接口(interface)和类的东西;当应用我对 JLS 的解释时 Foo<? super Runnable>据说是有效的。所以我可能误解了一些东西。这是我的尝试:

来自 JLS 的那部分:

A parameterized type consists of a class or interface name C and an actual type argument list <T1 , ... , Tn>. 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 = G<T1, ..., Tn> be a parameterized type. It must be the case that, after P is subjected to capture conversion (§5.1.10) resulting in the type G<X1, ..., Xn>, for each actual type argument Xi, 1 <= i <= n , Xi <: Bi[A1 := X1, ..., An := Xn] (§4.10), or a compile time error occurs.

将其应用于 P = Foo<? super Runnable> : 给出 C = Foo , n = 1, T1 = ? super Runnable B1 = Number .

对于捕获转换这部分definition of capture conversion适用:

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>其中 X是一个具有上限的新类型变量 Number和下限 Runnable .我没有看到任何明确禁止此类类型变量的内容。

B1 = Number 中没有类型变量, 所以 Bi[A1 := X1, ..., An := Xn] 仍然是简单的 Number . XNumber作为上限(来自捕获转换),并根据 the subtyping rules “类型变量的直接父类(super class)型是其绑定(bind)中列出的类型”,因此 X <:Number (= Bi[A1 := X1, ..., An := Xn]),所以这个参数在它的范围内。 (但事实并非如此!)

遵循相同的推理每个 通配符都在其范围内,所以这里有些地方不对......但是这个推理到底哪里出了问题?如果应用得当,这些规则如何运作?

最佳答案

关于泛型的 JLS 不完整,您发现了其中的另一个漏洞。几乎没有讨论类型变量的下限,而且我在 X 的规范中也没有看到任何限制。有上限 Number和下限 Runnable .他们可能遗漏了它。

直觉上,必须至少有一种可能的类型同时满足类型变量的上限和下限,否则该变量和使用该变量的所有类型都将无用。由于这几乎可以肯定是编程错误,因此编译应该会失败。

检查上限和下限是否构成空类型集很容易。下界的所有父类(super class)型都是已知的;至少其中一个应该是上限,否则没有类型在两个范围内。

--

两个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=Thread,捕获转换失败。

关于java - Java 泛型类型中的通配符参数在其范围内的正式条件是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7003009/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com