Две причины:
Чтобы избежать ненужных приведений:
Вы должны использовать вариант T
для таких случаев:
public <T extends Set> T firstOf(List<T> l) {
return l.get(0);
}
С ?
это станет:
public Set firstOf2(List<? extends Set> l) {
return l.get(0);
}
... который не дает такое же количество информации вызывающей стороне метода firstOf
. Первая версия позволяет вызывающей стороне сделать это:
SubSet first = firstOf(listOfSubSet);
во второй версии вы вынуждены использовать приведение для компиляции:
SubSet first = (SubSet)firstOf(listOfSubSet);
Для обеспечения соответствия типов аргументов:
public <T extends Set> boolean compareSets(List<T> a, List<T> b) {
boolean same = true;
for(T at : a) {
for (T bt: b) {
same &= at.equals(bt);
}
}
return same;
}
Не существует прямого эквивалента использования ?
вместо T
для этого. Обратите внимание, что из-за единой диспетчеризации Java в приведенной выше версии компилятор вызовет метод at
equals(T)
, который может значительно отличаться от метода at
* equals(Set)
или equals(Object)
.