在 Java 语言规范第 11 版第 4.10.2 节中,包含通配符的参数化类型是否没有直接超类型?

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?

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

Given a generic type declaration C<F₁,…,Fₙ> (n > 0), the direct supertypes of the parameterized type C<T₁,…,Tₙ>, where Tᵢ (1 ≤ i ≤ n) is a type, are all of the following:

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

可以找到“是一种类型”的含义 at the top of section 4.1:

There are two kinds of types in the Java programming language: primitive types (§4.2) and reference types (§4.3).

引用类型(我们这里不是在谈论基元,这是肯定的)is simply a ClassOrInterfaceType, a TypeVariable or an ArrayType.

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

(它is, in fact, a kind of TypeArgument. You might think hazily and naïvely as I once did that a wildcard is a wonky kind of TypeVariable, and hence a type, but you would be incorrect.)

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

这个读数正确吗?也就是说,我的演绎推理正确吗?

(也许值得注意的是,有些类型可以“包含”包含通配符的参数化类型(如 defined in section 4.5.1)。)

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

Given a generic type declaration C<F1,...,Fn> (n > 0), the direct supertypes of the parameterized type C<R1,...,Rn> where at least one of the Ri (1 ≤ i ≤ n) is a wildcard type argument, are the direct supertypes of the parameterized type C<X1,...,Xn> which is the result of applying capture conversion to C<R1,...,Rn> (§5.1.10).

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

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

The relationship of wildcards to established type theory is an interesting one, which we briefly allude to here. Wildcards are a restricted form of existential types. Given a generic type declaration G, G<?> is roughly analogous to Some X <: B. G.

还有:

Raw types are closely related to wildcards. Both are based on existential types. Raw types can be thought of as wildcards whose type rules are deliberately unsound, to accommodate interaction with legacy code. Historically, raw types preceded wildcards; they were first introduced in GJ, and described in the paper Making the future safe for the past: Adding Genericity to the Java Programming Language by Gilad Bracha, Martin Odersky, David Stoutamire, and Philip Wadler, in Proceedings of the ACM Conference on Object-Oriented Programming, Systems, Languages and Applications (OOPSLA 98), October 1998.

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

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

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

而不是:

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

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

因此它本身没有超类型。

but a parameterized type C<T₁,…,Tₙ>, where at least one Tₙ is a wildcard has no direct supertypes…

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

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

Capture conversion is what allows the compiler to manufacture a placeholder type name for the captured wildcard, so that type inference can infer it to be that type.