【问题标题】:In the Java Language Specification version 11, section 4.10.2, is it true that a parameterized type containing a wildcard has no direct supertypes?在 Java 语言规范版本 11 的第 4.10.2 节中,包含通配符的参数化类型是否没有直接超类型?
【发布时间】:2021-11-30 10:23:36
【问题描述】:

the Java Language Specification, version 11, section 4.10.2 中,部分内容是在讨论参数化类型的直接超类型时:

给定泛型类型声明 C (n > 0),参数化类型 C 的直接超类型,其中 Tᵢ (1 ≤ i ≤ n)是一个类型,都是以下几种:

(然后它列出了一系列适用于此类参数化类型的规则。这些规则与这个问题几乎无关。它们的相关性仅在于它们为某些参数化类型定义了直接超类型。)

“是类型”是什么意思可以查到at the top of section 4.1

Java 编程语言中有两种类型:原始类型(第 4.2 节)和引用类型(第 4.3 节)。

一个引用类型(我们在这里不是在谈论原语,这是肯定的)is simply a ClassOrInterfaceType, a TypeVariable or an ArrayType

因此通配符不是一种类型。

(它是is, in fact, a kind of TypeArgument。你可能会像我曾经做过的那样模糊而天真地认为通配符是一种不稳定的TypeVariable,因此是一种类型,但you would be incorrect。)

因此,将所有这些放在一起,我对第 4.10.2 节相关部分的阅读是:

  • “参数化类型 C,其中 Tᵢ (1 ≤ i ≤ n) 是一个类型”具有各种直接超类型…
  • ...但是参数化类型 C,其中至少有一个 Tₙ 是通配符,具有 no 直接超类型...
    • ...因为本节中列出的规则并不完全或部分适用于包含至少一个通配符的参数化类型...
      • ...因为通配符不是类型,所以永远不会满足“其中 Tᵢ (1 ≤ i ≤ n) 是类型”的条件。

这是正确的阅读方式吗?换句话说,我的演绎推理正确吗?

(顺便提一下,有些类型可以“包含”包含通配符的参数化类型(如defined in section 4.5.1)。)

【问题讨论】:

  • 进一步阅读!下一条规则讨论“给定泛型类型声明 C (n > 0),参数化类型 C 的直接超类型至少在哪里其中一个 Ri (1 ≤ i ≤ n) 是通配符类型参数"
  • 啊,谢谢你;错过了那部分!所以我的阅读是正确的,但正如您正确指出的那样,包含至少一个通配符的参数化类型的超类型是那些将捕获转换应用于原始类型参数的超类型。

标签: java jls


【解决方案1】:

通配符是 JAVA 中的类型,它们是“存在类型”。从您的同一个链接页面:

通配符与既定类型理论的关系是 有趣的一个,我们在这里简要提及。通配符是一个 存在类型的受限形式。给定一个泛型类型声明 G, G> 大致类似于 Some X <: b. g.>

还有:

原始类型与通配符密切相关。两者均基于 存在类型。原始类型可以被认为是其类型的通配符 规则故意不健全,以适应与遗产的互动 代码。从历史上看,原始类型在通配符之前;他们是第一个 在 GJ 中介绍,并在论文“使未来安全”中进行了描述 过去:向 Java 编程语言添加通用性 Gilad Bracha、Martin Odersky、David Stoutamire 和 Philip Wadler,在 ACM 面向对象编程会议论文集, 系统、语言和应用程序 (OOPSLA 98),1998 年 10 月。

存在类型向调用者隐藏其实现中的类型。为了使 X 在 T 中存在,X 的身份不能从任何调用对象中获知。所知道的只是定义时提供的一组操作。

来自Raw Types in Java: 原始类型是没有类型参数的通用接口或类的名称:

List list = new ArrayList(); // raw type

代替:

List<Integer> listIntgrs = new ArrayList<>(); // parameterized type

所以它不是 JAVA 中经典意义上的类型:原始类型或引用类型,但它是编译器有规则并知道如何处理的一种特殊形式的类型。这是否意味着它真的不是一种类型?我认为不,它是一种伪类型或未知类型,因为没有更好的词,因为它可以在不知道它是什么类型的情况下声明和使用。

因此它本身不会有超类型。

但是一个参数化类型 C,其中至少一个 Tₙ 是 通配符没有直接的超类型……

但是,正如@Sweeper 指出的那样,如果您的参数化类型具有至少一个通配符类型参数,那么您可以使用捕获转换找到超类型。

我在 SO 上找到了捕获转换的定义:What is a capture conversion in Java and can anyone give me examples?

捕获转换允许编译器制造一个 捕获的通配符的占位符类型名称,以便该类型 inference 可以推断它是那种类型。

【讨论】:

【解决方案2】:

您引用的部分确实没有说明具有至少一个通配符类型参数的参数化类型。它们的直接超类型是在您引用的部分之后指定的:

给定一个泛型类型声明 C (n > 0),参数化类型 C 的直接超类型,其中至少一个 Ri (1 ≤ i ≤ n) 是通配符类型参数,是参数化类型 C 的直接超类型,它是将捕获转换应用于 C (@ 987654321@).

基本上,要找到具有至少一个通配符类型参数的类型的直接超类型,您首先应用捕获转换,然后您将获得一个参数化类型,它仅“类型”作为类型参数,因为捕获转换转换用于类型变量的通配符。之后,您可以使用您引用的规则来查找其超类型。

【讨论】:

    猜你喜欢
    • 2021-11-29
    • 2015-09-22
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多