Reputation: 2979
I came across following image on oracle docs explaining inheritance in the context of generics:
Doubts
List<Integer>
is not a sub type of List<Number>
, but then how exactly List<Number>
is a sub type of List<? extends Number>
? Is it just how it is done by java designers? Is there any more details to it, possibly low level?List<Number>
is sub type of List<? extends Number>
?Upvotes: 1
Views: 82
Reputation: 271175
but then how exactly
List<? extends Number>
is a sub type ofList<? extends Number>
?
They are the same type! Did you mean:
but then how exactly
List<? extends Integer>
is a sub type ofList<? extends Number>
?
List<T>
means "a list of T
s", whereas List<? extends T>
means "a list of some unknown type, but I know it's a subclass of T
". In other words, what List<Number>
is is "set in stone", whereas List<? extends Number>
can be one of many things: List<Integer>
, List<Double>
, List<Number>
and so on. We don't know.
If you have understood this nuance, you shouldn't find the fact that you can't add Integer
s to a List<? extends Number>
surprising. Why? Because the List<? extends Number>
could very well be a List<Double>
. You can't add Integer
s to List<Double>
, can you?
Now the answer to the question should be clear, List<? extends Integer>
could be a list of any subclass of Integer
, whereas List<? extends Number>
could be a list of any subclass of Number
. Since, Integer
extends Number
, any list of a subclass of Integer
must also be a list of a subclass of Number
.
But note that a list of Integer
is not a list of Number
, since you can't add Double
s to a list of Integer
, but you can to a list of Number
.
How
List<Number>
is sub type ofList<? extends Number>
?
This is kind of "by definition" of the <? extends T>
syntax. There is no reason not to allow <T>
itself. And I do agree extends
is misleading here.
Also note that this is not really "inheritance". All the types involved here are really just the same JVM type List
, which is also an interface. Inheritance happens between classes. Your wording in the question body - "subtype" - is more appropriate.
Upvotes: 1
Reputation: 346
I used to have the same question as you.
It can be understood using set theory:
List<? extends Number>
contains List<Number>
, List<Byte>
, List<Double>
, List<Float>
, List<Integer>
, List<Short>
, List<Long>
. You can think of List<? extends Number>
as a set of 7 elements listed before. When two non-empty sets A and B are equal. It is not wrong to state that A is a subset of B and B is a subset of A.
List<? extends Number>
contains List<Number>
as its element. Therefore, List<Number>
is a sub-type of List<? extends Number>
.
Hope this will help!
Upvotes: 0