Ниже приведена отрывок из this link, и я думаю, что он отвечает на ваш вопрос достаточно хорошо.
Рассмотрите проблему написания процедуры, которая выводит все элементы в коллекции. Вот как вы можете записать его в старой версии языка (то есть, до 5,0 релиз):
void printCollection(Collection c) {
Iterator i = c.iterator();
for (k = 0; k < c.size(); k++) {
System.out.println(i.next());
}
}
А вот наивная попытка написать его с помощью дженериков (и новый для синтаксиса цикла):
void printCollection(Collection<Object> c) {
for (Object e : c) {
System.out.println(e);
}
}
проблема заключается в том, что эта новая версия гораздо менее полезны, чем старый один. В то время как старый код можно было вызывать с любым типом коллекции в качестве параметра, новый код принимает только Collection, который, как только что продемонстрировал , не является супертипом всех видов коллекций !
Так что же такое супертип всех видов коллекций? Написано Коллекция (произносится как «коллекция неизвестных»), то есть коллекция , тип элемента которой соответствует чему угодно. Это называется подстановочным знаком по очевидным причинам. Мы можем написать:
void printCollection(Collection<?> c) {
for (Object e : c) {
System.out.println(e);
}
}
и теперь, мы можем назвать это с любым типом коллекции.