Что такое wildcards и в чём их отличие от ограничений обобщений?

Допустим, у нас есть некий класс Dog с универсальным параметром T, который extends Number (то есть, T - является или самим классом Number или производным от него):

class Dog<T extends Number> {}

С этим примером всё ясно. Но что такое конструкция <? extends T> и <? super T>. Почему тут знак вопроса (?), в чем их отличие, и где использовать? А главное - зачем они нужны? Прошу дать понятный ответ, без сложных формулировок, только начала изучать Джаву.


Ответы (1 шт):

Автор решения: Andrey Tabakov

Знак ? означает, что сам конкретный тип нам не очень интересен, но нам интересны его свойства. Например расширяет (extends) ли он определённый тип или реализует (super) его.

Иногда можно встретить код вида:

int getHash(Comparable<?> comparable) { // просто из головы пример
  return comparable.hashCode();
}

В этом случае нам же неважно, что он сравнивает, мы просто хотим взять его свойство, мы будем понимать, что это какой-то сравнимый тип, но нам всё равно что там внутри, мы сейчас не работаем с его методами, которые этот тип требуют.

Дальше рекомендую поизучать, что такое PECS принцип - Producer Extends, Consumer Super. Именно там применяются конструкции вида <? extends T> и <? super T>. Они ограничивают возможные действия, как бы сужают контекст типа, но сам тип при этом не имеет значения.

Хотя тут уже всё разжевали: Использование wildcard в Generics Java

→ Ссылка