1
<T extends Number> void m1(List<T> list) {
    list.add(list.get(0)); 
}

void m2(List<? extends Number> list) {
    list.add(list.get(0)); 
}

I found difficult to understand the difference between above two methods.
First method m1() compiles successfully, but method m2() produces a compiler error:

The method add(capture#1-of ? extends Number) in the type List<capture#1-of ? extends Number> is not applicable for the arguments (capture#2-of ? extends Number)

Tom
  • 16,842
  • 17
  • 45
  • 54

1 Answers1

2

Because you cant add an iten on a list of type with upper bounds! You could have a List or List, where one doesnt fit in the other for modifications operations!

List<? extends Number> list = new ArrayList<Integer>();
List<? extends Number> list = new ArrayList<Double>();
List<? extends Number> list = new ArrayList<Long>();

In this case, the variable list could have any type in instance that extends Number. So you can pass it in your method, for example. But there, you don't really know which the type could be. You could have a ArrayList<Integer> and saying to it add a new Double. In compile time makes sense, because Double extends Number, but in runtime the list could no be of this type and throw an Exception.

Just remember that, when you use the upper bounds, <? extends T>, you can't modify the list, just read it! There is the Oracle tutorial (see Wildcards chapter contents - Upper Bounded Wildcards, Lower Bounded Wildcards etc.)

rosshjb
  • 581
  • 1
  • 8
  • 26
Bruno
  • 2,889
  • 1
  • 18
  • 25