42

From this Oracle tutorial,

Although Integer is a subtype of Number, List<Integer> is not a subtype of List<Number> and, in fact, these two types are not related.

The common parent of List<Number> and List<Integer> is List<?>.

My question is about the second sentence. How can we say that List<?> is the common parent of List<Number> and List<Integer>?

? stands for an unknown type, which could be any reference type. Even if I say that ? would be Object here, Object being the common parent of Integer and Number does NOT mean that List<Object> becomes a common parent of List<Integer> and List<Number>.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Solace
  • 8,612
  • 22
  • 95
  • 183
  • 4
    `List>` means that you don't know what its type is (and you don't care either). So any `List<>` is a `List>`. – biziclop Jun 24 '16 at 08:45
  • 2
    I don't think it is meant in the sense of an inheritance tree. But that is only speculation on my side. – Fildor Jun 24 '16 at 08:45
  • 4
    I know this is not a satisfying answer, but ```List``` can be assigned to ```List>``` freely i.e. ```List>``` can be seen as a parent of ```List```. The same goes for ```List```. So in a way, ```List>``` _can be seen as_ a common parent. – Jorn Vernee Jun 24 '16 at 08:47
  • `>` stands for object class if used alone – bananas Jun 24 '16 at 08:51
  • 1
    @JornVernee Actually this is the only explanation which is making sense, in a general way, so far in my head. – Solace Jun 24 '16 at 08:57
  • 1
    @asteriskNinja used alone as in? – Solace Jun 24 '16 at 08:58
  • It probably put it like that because it was about to introduce you bounded wildcards. Because `List extends Number>` seem to be a better 'parent' for both. – kazenorin Jun 24 '16 at 08:58
  • @kazenorin It gets slightly [complicated](http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super) there. – biziclop Jun 24 '16 at 09:02
  • 3
    I think it's better to look at this problem from the other side, lets start with `List>` class then think about contract that `List>` requires (we can get reference type, we can put only `null`s, we can ask for `size()`). Then ask yourself if `List` fully implements this contract, the answer is yes – csharpfolk Jun 24 '16 at 09:06
  • 1
    Highly relevant: http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ207 – Marco13 Jun 24 '16 at 15:54
  • @Marco13 Thank you for sharing. – Solace Jun 24 '16 at 17:15
  • 1
    Also, if I remember correctly, mechanically speaking, Java generics silently treat objects as `Object`, then implicitly cast them back to the original type when you access them (e.g. `List` treats everything in the `List` as an `Object` internally, then casts it back to `Integer` when you access it). In effect, `List`'s internal workings treat every `List` as `List>`, so by extension `List>` can be seen as every `List`'s common parent (where `T` represents any type). I may be misremembering, it's something I saw in a comparison of C++, C#, and Java generic programming. – Justin Time - Reinstate Monica Jun 24 '16 at 19:22
  • 1
    @JustinTime *"In effect, List's internal workings treat every List as List>"* You're correct that `List`'s internal workings use essentially non-generic code but wildcards have special semantics due to capture conversion so the analogy isn't particularly good. – Radiodef Jun 24 '16 at 19:37
  • 1
    @Radiodef Oh, my bad. Wasn't aware of the special semantics. Thanks for pointing that out. – Justin Time - Reinstate Monica Jun 25 '16 at 04:48

5 Answers5

29

The context you need to understand is not of Integer or Number but it's the List. Let's suppose you were the one creating the List class then how would you create the class so it will only support a specific type of class.

Yes, that List class won't use Object as its type but instead use a wild card ?.

As documentation of WildCards say

So what is the supertype of all kinds of collections? It's written Collection<?> (pronounced "collection of unknown")

Same thing can be said for List.

So what is the supertype of all kinds of Lists? It's written List<?> (pronounced "List of unknown")

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
Basit Anwer
  • 6,742
  • 7
  • 45
  • 88
  • 4
    Firstly, thank you for pointing me to the article; it seems to be some other version of the same tutorial that I am reading. Now, after reading the intro, I am gathering that the gist of it is that since we can pass just _any_ `Collection` to a method which is declared to take a `Collection>`, it _implies_ that `Collection>` is the parent of all kinds of `Collection`s. Is that correct? – Solace Jun 24 '16 at 09:36
  • 3
    That is, the reason lies in something like polymorphism, right? "Since a B or a C can be used in a place where an A is expected, it _implies that_ B and C are subtypes of A." Right? – Solace Jun 24 '16 at 09:38
  • 3
    Yes. You can throw in a `Collection<>` everywhere but not `Collection` because then it will become a strongly typed `Collection` – Basit Anwer Jun 24 '16 at 09:40
12

We can prove that List<?> is a supertype of List<Number> and List<Integer>.

From JLS 4.10.2 (emphasis mine):

Given a generic type declaration C<F1,...,Fn> (n > 0), the direct supertypes of the parameterized type C<T1,...,Tn>, where Ti (1 ≤ i ≤ n) is a type, are all of the following:

  • ...

  • C<S1,...,Sn>, where Si contains Ti (1 ≤ i ≤ n) (§4.5.1)

by replacing C with List and n=1, we know that List<?> is a direct supertype of List<Number> and List<Integer> if ? contains Number and Integer.

We can prove that ? contains Number and Integer because from JLS 4.5.1:

The wildcard ? extends Object is equivalent to the unbounded wildcard ?.

and further on:

A type argument T1 is said to contain another type argument T2, written T2 <= T1, if the set of types denoted by T2 is provably a subset of the set of types denoted by T1 under the reflexive and transitive closure of the following rules (where <: denotes subtyping (§4.10)):

  • ? extends T <= ? extends S if T <: S
  • ...
  • T <= ? extends T

we can use the above rules to prove that Number <= ?, because Number <= ? extends Number <= ? extends Object = ?.

dejvuth
  • 6,986
  • 3
  • 33
  • 36
  • 5
    This is really the most important answer. A lot of Java programmers seem to understand subtyping in Java as inheritance (`extends`/`implements`), but that is not how the JLS is written. Inheritance is only one way to have subtyping in Java. The tutorial isn't just making an analogy. `List` and `List` are actually subtypes of `List>` despite the fact that there is no inheritance and all three types have the same class. – Radiodef Jun 24 '16 at 19:43
5

The tutorial is about wildcards. So they want to explain when and how you should use them. When you read ahead there is the example code:

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number>  numList = intList;  // OK. List<? extends Integer> is a subtype of List<? extends Number>

You only can do this assignment if ? is the common parent of Integer and Number. I think in the relation with wildcards and generics it is possible to say that:

List<?> is the common parent of List<Number> and List<Integer>

because it is necessary to see the context of the tutorial.

wake-0
  • 3,918
  • 5
  • 28
  • 45
  • This section is about _inhertance and_ wildcards. It's titled "Wildcards and Subtyping". Actually, if you start reading from the start of the section, they are talking about inheritance. This section is about how the phenomena of inheritance and wildcards work together/affect each other etc. – Solace Jun 24 '16 at 08:53
3

Here are the types that the methods have in Java with generics:

interface Collection<E> {
...
public boolean contains(Object o);
public boolean containsAll(Collection<?> c);
...
}

The first method does not use generics at all! The second method is our first sight of an important abbreviation. The type Collection stands for:

Collection<? extends Object>

Extending Object is one of the most common uses of wildcards, so it makes sense to provide a short form for writing it.

bananas
  • 1,176
  • 2
  • 19
  • 39
3

You are mixing the concepts of OOP inheritance or concrete types with the one of generic types and relationships between those generics.

One sentence in the tutorial about Wildcards and Subtypes says it all:

In order to create a relationship between these classes ... use an upper bounded wildcard

For generic type relationships ? is simply the most upper bounded from the possible wildcards ? extends <type> (upper bounded wildcard), ? super <type> (lower bounded wildcard) and the actual type (the exact match or "upper and lower bounded wildcard").

The wildcards are used to get the both concepts of generics and OOP to work neatly with each other but it is not the same. Simply put: List<?> is the common parent of List<Integer> and List<Number> because the wildcard relationship is specified as such that any other wildcard creates a subtype relationship with ?. This is more or less the informal explanation, look at dejvuth's answer for the concrete parts of the specification.

makadev
  • 1,034
  • 15
  • 26