Java generics: Collections.max() signature and Comparator

comparator, generics, java

Solution

Josh Bloch's mnemonic PECS is useful here. It stands for:

Producer `extends`, Consumer `super`

This means that when a parameterized type being passed to a method will produce instances of `T` (they will be retrieved from it in some way), `? extends T` should be used, since any instance of a subclass of `T` is also a `T`.

When a parameterized type being passed to a method will consume instances of `T` (they will be passed to it to do something), `? super T` should be used because an instance of `T` can legally be passed to any method that accepts some supertype of `T`. A `Comparator<Number>` could be used on a `Collection<Integer>`, for example. `? extends T` would not work, because a `Comparator<Integer>` could not operate on a `Collection<Number>`.

Edit: To clarify a little more on get/put (produce/consume):

public T something();
       ^

The above is a method that produces `T`.

public void something(T t);
                      ^

The above is a method that consumes `T`.

"Producer `extends`, Consumer `super`" applies to how the method a parameterized object is being passed to is going to be using that object. In the case of `Collections.max()`, items will be retrieved from the `Collection`, so it is a producer. Those items will be passed as arguments to the method on `Comparator`, so it is a consumer.

Problem

I understand the get and put principle for collections: if a method takes in a collection that it will write a type T to, the parameter has to be `Collection<? super T>`, whereas if it will read a type T from, the parameter has to be `Collection<? extends T>`. But could someone please explain the `Collections.max()` signature: ``` public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) ``` In particular why is it `Comparator<? super T>` instead of `Comparator<? extends T>` ?

Original source