2

Why there is <?e extends T> instead of <T> in unmodifiable APIs of java.util.Collections e.g. consider unmodifiableLis API

public static <T> List<T> unmodifiableList(List<? extends T> list)

Why not, just

public static <T> List<T> unmodifiableList(List<T> list)

Edit: This is not duplicate of When do Java generics require instead of and is there any downside of switching. That question intend to find the importance of <? extends T> over <T> and what would be the impact if change is done from one to other. I understand the difference in both syntax (<? extends T> and <T>), however in case of unmodifiable collection APIs, context (and hence my question) is different.

Community
  • 1
  • 1
Vasu
  • 4,862
  • 8
  • 42
  • 48
  • 1
    I've voted to reopen this question, as I believe that it is (quite subtly) a different question from the [alleged duplicate](http://stackoverflow.com/questions/897935/when-do-java-generics-require-extends-t-instead-of-t-and-is-there-any-down?). This here deals with tricking unmodifiable lists into being as-if-declaration-site-covariant, while the other one deals with covariant correlation of two generic method arguments. Same language tool, different problem. – Lukas Eder Jun 20 '14 at 06:07

1 Answers1

3

It's so you can do things like this:

List<Integer> intList = new ArrayList<Integer>();
// . . . populate intList

// now create an unmodifiable version:
List<Number> numList = Collections.unmodifiableList(intList);

Note that because generics are not covariant, so you cannot assign from a List<Integer> to a List<Number>:

numList = intList;

even though each element would be assignment-compatible. If you changed the signature of unmodifiableList as you suggest, it would run into the same problem (since the return type in my example would be forced to be List<Integer> once the parameter was bound).

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • the version which I suggested would return List and so `List numList = Collections.unmodifiableList(intList)` would be possible, but not `List = Collections.unmodifiableList(intList)`. Is not this expected ? – Vasu Jun 01 '14 at 03:07
  • @Kailash - With the current api, it is not expected and you _could_, in fact, do `List numList = Collections.unmodifiableList(intList)`. This is often a useful thing. – Ted Hopp Jun 01 '14 at 03:20
  • As no one has any other explanation, I am going to accept your answer. – Vasu Jun 20 '14 at 05:09