How would contravariance be used in Java generics?

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;
}

Leave a Comment