MsA
MsA

Reputation: 2979

Understanding inheritance in the context of generics wildcard

I came across following image on oracle docs explaining inheritance in the context of generics:

enter image description here

Doubts

  1. I know 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?
  2. How List<Number> is sub type of List<? extends Number>?

Upvotes: 1

Views: 82

Answers (2)

Sweeper
Sweeper

Reputation: 271175

but then how exactly List<? extends Number> is a sub type of List<? extends Number>?

They are the same type! Did you mean:

but then how exactly List<? extends Integer> is a sub type of List<? extends Number>?

List<T> means "a list of Ts", 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 Integers to a List<? extends Number> surprising. Why? Because the List<? extends Number> could very well be a List<Double>. You can't add Integers 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 Doubles to a list of Integer, but you can to a list of Number.

How List<Number> is sub type of List<? 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

DuongH.
DuongH.

Reputation: 346

I used to have the same question as you.

It can be understood using set theory:

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

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

Related Questions