мнемоника Джоша Блоха PECS полезна здесь. Он обозначает:
Производитель extends
, Потребитель super
Это означает, что когда параметризованный тип, передаваемый методу, будет создавать экземпляров T
(они будут каким-то образом извлечены из него), следует использовать ? extends T
, поскольку любой экземпляр подкласса T
также является T
.
Когда параметризованный тип, передаваемый методу, будет потреблять экземпляров T
(они будут переданы ему для выполнения каких-либо действий), следует использовать ? super T
, поскольку экземпляр T
может быть законно передан любому методу, который принимает некоторый супертип T
. Например, Comparator<Number>
можно использовать для Collection<Integer>
. ? extends T
не будет работать, потому что Comparator<Integer>
не может работать на Collection<Number>
.
Edit:
Чтобы уточнить немного больше о получении / сдаче (производстве / потреблении):
public T something();
^
Выше приведен метод, который производит T
.
public void something(T t);
^
Выше приведен метод, который потребляет T
.
«Производитель extends
, Потребитель super
» применяется к тому, как метод, которому передается параметризованный объект, будет использовать этот объект. В случае Collections.max()
элементы будут извлечены из Collection
, так что это производитель. Эти элементы будут переданы в качестве аргументов методу Comparator
, поэтому он является потребителем.