Разница между
T max(Collection<? extends T> coll)
и
T wrongMax(Collection<T> xs)
заключается в том, что возвращаемый тип второй версии в точности совпадает с типом элемента коллекции T
, тогда как в первой версии T
может быть супер тип типа элемента.
Второй вопрос: причина для T extends Object
гарантирует, что T
является классом, а не интерфейсом.
Обновление: немного более «естественная» демонстрация разницы: предположим, вы определяете эти два метода:
static void happy(ColoredPoint p, Point q) {}
static void happy(Point p, ColoredPoint q) {}
И назовите первый из них следующим образом:
happy(coloredPoint, min(points));
happy(coloredPoint, wrongMin(points));
Механизм вывода типа мог бы вывести, что в первом вызове тип возврата min
должен быть Point
, и код будет скомпилирован. Второй вызов не смог скомпилировать, поскольку вызов happy
неоднозначен.
К сожалению, механизм вывода типа не достаточно мощный, по крайней мере, на Java 7, поэтому на самом деле оба вызова не скомпилируются. Разница в том, что первый вызов можно зафиксировать, указав параметр типа, как в Algorithms.<Point>min
, тогда как для фиксации второго вызова потребуется явное литье.