This is a Wildcard Capture problem.
TL;DR - when you use a wildcard (be it with super
or extends
) in the Generic Collection type definition, getting element from that collection and casting it appropriately can be considered safe, while adding element into the collection is not, and this mechanism is implemented for the safety purpose.
Let's examine the example given in the Oracle Documentation, which demonstrates the reason of why this safety is needed (this example uses extends
but same principle applies for super
):
The code:
import java.util.List;
public class WildcardErrorBad {
void swapFirst(List extends Number> l1, List extends Number> l2) {
Number temp = l1.get(0);
l1.set(0, l2.get(0)); // expected a CAP#1 extends Number, got a CAP#2 extends Number;
l2.set(0, temp); // expected a CAP#1 extends Number, got a Number
}
}
does not compile, as it is attempting an unsafe operation, because, if you will invoke this method as follows:
List li = Arrays.asList(1, 2, 3);
List ld = Arrays.asList(10.10, 20.20, 30.30);
swapFirst(li, ld);
while List
and List
both fulfill the criteria of List extends Number>
, it is clearly incorrect to take an item from a list of Integer values and attempt to place it into a list of Double values.
Another example I liked is given by Jon Skeet, and it looks like this.
You might also want to read this.