Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 935
Solace Avatar asked Jun 24 '16 08:06

Solace


4 Answers

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

like image 152
Basit Anwer Avatar answered Oct 30 '22 18:10

Basit Anwer


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 = ?.

like image 30
dejvuth Avatar answered Oct 30 '22 18:10

dejvuth


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.

like image 5
Kevin Wallis Avatar answered Oct 30 '22 18:10

Kevin Wallis


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.

like image 3
makadev Avatar answered Oct 30 '22 17:10

makadev