1

In the Java Language Specification, version 11, section 4.10.2, it reads, in part, while discussing direct supertypes of parameterized types:

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:

(Then it lists a bunch of rules that apply to such parameterized types. These rules are mostly irrelevant for this question. They are relevant only in that they define direct supertypes for some cases of parameterized types.)

What "is a type" means can be found 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).

A reference type (we're not talking about primitives here, that's for sure) is simply a ClassOrInterfaceType, a TypeVariable or an ArrayType.

Therefore a wildcard is not a kind of type.

(It 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.)

So putting all this together, my reading of the relevant part of section 4.10.2 is:

  • "the parameterized type C<T₁,…,Tₙ>, where Tᵢ (1 ≤ i ≤ n) is a type" has direct supertypes of various kinds…
  • …but a parameterized type C<T₁,…,Tₙ>, where at least one Tₙ is a wildcard has no direct supertypes
    • …because the rules that are listed in this section do not apply wholly or partially to parameterized types containing at least one wildcard…
      • …because a wildcard is not a type, so the "where Tᵢ (1 ≤ i ≤ n) is a type" condition is never met.

Is this a correct reading? In other words, is my deductive reasoning correct?

(It is perhaps worth noting in passing that there are types that can "contain" a parameterized type containing wildcards (as defined in section 4.5.1).)

Laird Nelson
  • 15,321
  • 19
  • 73
  • 127
  • 2
    Read further! The next rule talks about "Given a generic type declaration C (n > 0), the direct supertypes of the parameterized type C **where at least one of the Ri (1 ≤ i ≤ n) is a wildcard type argument**" – Sweeper Oct 11 '21 at 17:16
  • Ah, thanks for that; missed that part! So my reading was right as far as it went, but as you quite rightly point out the supertypes of a parameterized type containing at least one wildcard are those that result from applying capture conversion to the original type arguments. – Laird Nelson Oct 11 '21 at 17:29

2 Answers2

4

The part you quoted indeed doesn't say anything about parameterised types with at least one wildcard type argument. What their direct super types are is specified just after the part you quoted:

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).

Basically, to find the direct super types of a type with at least one wildcard type argument, you first apply capture conversion, and then you will get a parameterised type that only "types" as the type parameters, as capture conversion converts the wildcards to type variables. After that, you can use the rule that you quoted to find its super types.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

Wildcards are types in JAVA, they are "existential types". From your same linked page:

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.

Also:

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.

An existential type hides a type within its implementation from the caller. For X to be existential in T, X's identity cannot be known from any calling object. All that is known is the set of operations provided at definition.

From Raw Types in Java: A raw type is a name for a generic interface or class without its type argument:

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

Instead of:

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

So it's not a type in the classic sense of types in JAVA: primitives or reference types, but it is a special form of type that the compiler has rules for and knows how to handle. Does that mean it really isn't a type? I would argue no, it is a psuedo-type or unknown type for lack of better words as it can be declared and used without knowing what it's type is.

Therefore it won't have a supertype in and of itself.

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

However, as @Sweeper pointed out, if you have parameterised types with at least one wildcard type argument, then you can find the super type using capture conversion.

I found this definition for capture conversion here on 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.

James Drinkard
  • 15,342
  • 16
  • 114
  • 137
  • Maybe that's all fair; I'm not qualified to say. I'm just going off the hyperlinked grammar in the specification: https://docs.oracle.com/javase/specs/jls/se11/html/jls-4.html#jls-Type – Laird Nelson Oct 11 '21 at 17:53
  • For later readers, there's also a very precise definition of "raw type": https://docs.oracle.com/javase/specs/jls/se11/html/jls-4.html#jls-4.8 – Laird Nelson Oct 11 '21 at 17:54
  • Well we are really splitting hairs here, but I think you can argue that wildcards aren't a type and then they are, but in a limited sense. – James Drinkard Oct 11 '21 at 17:56