From this Oracle tutorial,
Although
Integer
is a subtype ofNumber
,List<Integer>
is not a subtype ofList<Number>
and, in fact, these two types are not related.The common parent of
List<Number>
andList<Integer>
isList<?>
.
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>
.
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")
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>
, whereSi
containsTi
(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 argumentT2
, writtenT2
<=T1
, if the set of types denoted byT2
is provably a subset of the set of types denoted byT1
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
= ?
.
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 ofList<Number>
andList<Integer>
because it is necessary to see the context of the tutorial.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With