I have a very basic question ragarding Java generics . I thought that both List<Number>
and List<? extends Number>
are homogeneous . Am I right or is there something fundamental I am missing ?
3 Answers
Generic types are more pedantic.
<? extends Number>
means Number or an unknown a sub class. If you obtain such a value it will be a Number
, but you cannot give a value of this type because you don't know which is valid.
The difference is in arguments and return values.
List<Number> numbers = new ArrayList<Number>();
Number n = 1;
numbers.add(n); // ok.
n = numbers.get(0); // ok
numbers.add(1); // ok.
List<? extends Number> numbers2 = new ArrayList<Double>();
numbers2.add(n); // not ok
n = numbers2.get(0); // ok
List<? super Number> numbers3 = new ArrayList<Serializable>();
numbers3.add(n); // ok
n = numbers3.get(0); // not ok.
super
is used in a few places to signify the type can be a super type. e.g.
In Collections, this method says the Comparator needs to be able to compare the same type or any super type.
public static <T> void sort(List<T> list, Comparator<? super T> c)
This means you can have
Comparator<Number> comparesAnyNumbers = ...
List<Integer> ints = ...
Collections.sort(ints, comparesAnyNumbers);

- 525,659
- 79
- 751
- 1,130
-
They are more specific, `
` means just Number not some other type as well. – Peter Lawrey Aug 31 '12 at 13:34 -
Could you provides details on the usefullness of `List super Number>` ? – gontard Aug 31 '12 at 13:48
-
1IMHO Its not terribly useful. ;) – Peter Lawrey Aug 31 '12 at 13:52
-
@PeterLawrey getting compilation issue for `numbers2.add(new Integer(2)); `? this should work right? – Nandkumar Tekale Aug 31 '12 at 13:52
-
@Nandkumar No, numbers2 is actually an `ArrayList
` – Peter Lawrey Aug 31 '12 at 13:56 -
@PeterLawrey : I used diamond `<>` there, no
. – Nandkumar Tekale Aug 31 '12 at 13:58 -
1@PeterLawrey from the compiler perspective, number2 is a `List extends Number>` not a `ArrayList
`. The instruction `numbers2.add(Double.valueOf(1d));` don't work too. – gontard Aug 31 '12 at 13:59 -
@gontard Correct, the point is; the list contains a unknown type which extends Number. – Peter Lawrey Aug 31 '12 at 14:02
-
1@PeterLawrey nothing (but `null`) could be added into `List extends Number>` ? – gontard Aug 31 '12 at 14:04
-
`List extends T>` : since we don't what is really `?` : you can't **add** item into it : this is a sort of `"read-only compile time checked list"`. – gontard Aug 31 '12 at 14:17
-
`List super T>` : since we don't what is really `?` : you can't **read** item from it : this is a sort of `"write-only compile time checked list"`. – gontard Aug 31 '12 at 14:19
-
@gontard Sort of but you can call `remove(0);` or `clear();` on it. ;) – Peter Lawrey Aug 31 '12 at 14:19
-
@gontard You can read an `Object` from `? super T` as every object is an `Object` – Peter Lawrey Aug 31 '12 at 14:20
-
@gontard `const` is a keyword in Java, you just can't use it anywhere. :D – Peter Lawrey Aug 31 '12 at 14:23
-
@PeterLawrey may be in `java 10` ;) – gontard Aug 31 '12 at 14:25
Generics are compile time language features, means, they don't exist in run-time. In generic mechanism, for compile-time checks, they are not homogeneous, i.e. if you want to use polymorphism in generic type.
Following gives you a compile time error, although it seems a valid definition:
List<Number> list = new ArrayList <Integer>();
whereas
List<? extends Number> list = new ArrayList <Integer>();
is valid. Moreover, you can't use wildcard types on the right side:
List list = new ArrayList <? extends Integer>();
won't be compiled.

- 5,231
- 6
- 34
- 40
List<Number>
--> List of Number
s (or instances of Number
)
List<? extends Number>
--> List any type which extends Number

- 17,667
- 4
- 54
- 79