Для достижения наилучших результатов вы должны использовать public static <T extends Comparable<? super T>> T max(T a, T b)
.
Проблема с <T extends Comparable<?>>
заключается в том, что это говорит о том, что тип T сравним с некоторым типом, но вы не знаете, что это за тип. Конечно, здравый смысл подсказывает, что класс, реализующий Comparable, должен иметь возможность быть сравнимым, по крайней мере, с самим собой (т. е. иметь возможность сравнивать объекты своего собственного типа), но технически ничто не мешает классу A реализовать Comparable<B>
, где А и Б не имеют ничего общего друг с другом. <T extends Comparable<T>>
решает эту проблему.
Но есть тонкая проблема с этим. Предположим, класс X реализует Comparable<X>
, и у меня есть класс Y, который расширяет X. Таким образом, класс Y автоматически реализует Comparable<X>
путем наследования. Класс Y также не может реализовать Comparable<Y>
, потому что класс не может дважды реализовать интерфейс с параметрами разных типов. На самом деле это не проблема, поскольку экземпляры Y являются экземплярами X, поэтому Y сопоставим со всеми экземплярами Y. Но проблема в том, что вы не можете использовать тип Y с вашей функцией <T extends Comparable<T>> T max(T a, T b)
, потому что Y не реализует Comparable<Y>
. Границы слишком строгие. <T extends Comparable<? super T>>
устраняет проблему, потому что достаточно, чтобы T был сопоставим с некоторым супертипом T (который включал бы все экземпляры T). Вспомните правило PECS — производитель extends
, потребитель super
— в этом случае Comparable
является потребителем (он принимает объект для сравнения), поэтому super
имеет смысл.
Это границы типа, используемые всеми функциями сортировки и упорядочения в библиотеке Java.
person
newacct
schedule
24.06.2011
if(a==null)
нет необходимости во вложенном предложении if. Сокращение блока доreturn b;
дает тот же результат (null
, когдаb
равноnull
,b
в противном случае). - person benjamin   schedule 28.11.2014