То, как вы это определили, не очень полезно, но оба из них имеют свои применения.
Давайте начнем со второго и рассмотрим реализацию List.containsAll()
:
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
Обратите внимание, что вы обычно хотите использовать неограниченный подстановочный знак, когда хотите угрожать всему как объекту.Как и в этом случае.Вы можете прочитать больше об этом здесь:
https://docs.oracle.com/javase/tutorial/java/generics/unboundedWildcards.html
Теперь давайте рассмотрим ваш первый пример с подстановочным знаком, ограниченным сверху.
Сначала, на ваш вопрос о том, какзаселить это.Вы можете сделать это, используя конструктор копирования:
class K implements Comparable<K> {
@Override
public int compareTo( K o) {
return 0;
}
}
class K2 implements Comparable<K2> {
@Override
public int compareTo(K2 o) { return 0; }
}
// Works
List<? extends Comparable<?>> list1 = new ArrayList<>(Arrays.asList(new K(), new K2()));
Полезное свойство заключается в том, что пользователь этого списка не сможет добавлять элементы в него без использования отражения (кроме нулей, но я бы не стал его называть).очень полезно).
Подробнее об этом можно прочитать здесь: https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html