Here's a relevant excerpt from Java Generics and Collections:
2.4. The Get and Put Principle
It may be good practice to insert wildcards whenever possible, but how do you decide
which wildcard to use? Where should you use extends
, where should you use super
,
and where is it inappropriate to use a wildcard at all?
Fortunately, a simple principle determines which is appropriate.
The Get and Put Principle: use an
extends
wildcard when you only get
values out of a structure, use a super
wildcard when you only put values into
a structure, and don't use a wildcard
when you both get and put.
We already saw this principle at work in the signature of the copy method:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
The method gets values out of the source src, so it is declared with an extends
wildcard,
and it puts values into the destination dst, so it is declared with a super
wildcard.
Whenever you use an iterator, you get values out of a structure, so use an extends
wildcard. Here is a method that takes a collection of numbers, converts each to a double,
and sums them up:
public static double sum(Collection<? extends Number> nums) {
double s = 0.0;
for (Number num : nums) s += num.doubleValue();
return s;
}