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 max(Collection extends T> coll,
Comparator super T> comp)
In particular why is it Comparator super T> instead of Comparator extends T> ?
解决方案
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 could be used on a Collection, for example. ? extends T would not work, because a Comparator could not operate on a Collection.
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.