Подтвердить что ты не робот

Является ли List <?> Общим родителем List <Integer> и List <Number>?

Из этого учебника Oracle,

Хотя Integer является подтипом Number, List<Integer> не является подтип List<Number> и, фактически, эти два типа не связаны.

Общий родительский элемент List<Number> и List<Integer> равен List<?>.

Мой вопрос касается второго предложения. Как мы можем сказать, что List<?> является общим родителем List<Number> и List<Integer>?

? обозначает неизвестный тип, который может быть любым ссылочным типом. Даже если я скажу, что ? будет Object здесь, Object является общим родителем Integer и Number НЕ означает, что List<Object> становится общим родителем List<Integer> и List<Number>.

4b9b3361

Ответ 1

Контекст, который вам нужно понять, не от Integer или Number, а от List. Предположим, что вы были тем, кто создал класс List, тогда как бы вы создали класс, чтобы он поддерживал только определенный тип класса.

Да, этот класс List не будет использовать Object в качестве своего типа, а вместо этого использовать wild card ?.

Как документация WildCards скажите

Итак, что такое супертип всех видов коллекций? Он написал Collection<?> (произносится как "коллекция неизвестных" )

То же самое можно сказать о List.

Итак, что такое супертип всех видов списков? Он написал List<?> (произносится как "Список неизвестных" )

Ответ 2

Мы можем доказать, что List<?> является супертипом List<Number> и List<Integer>.

Из JLS 4.10.2 (выделено мной):

Учитывая объявление универсального типа C < F1,..., Fn > (n > 0), прямые супертипы параметризованного типа C<T1,...,Tn>, где Ti (1 ≤ я ≤ n) является типом, являются следующими:

  • ...

  • C<S1,...,Sn>, где Si содержит Ti (1 ≤ я ≤ n) (§4.5.1)

заменив C на List и n=1, мы знаем, что List<?> является прямым супертипом List<Number> и List<Integer> , если ? содержит Number и Integer.

Мы можем доказать, что ? содержит Number и Integer, потому что из JLS 4.5.1

Подстановочный знак ? extends Object эквивалентен неограниченному шаблону ?.

и далее:

Аргумент типа T1 называется содержит другой аргумент типа T2, написанный T2 <= T1, если набор типов, обозначаемый T2, является предположительно подмножество множества типов, обозначаемое T1 при рефлексивном и транзитивном замыкании следующих правил (где <: обозначает подтипирование (§4.10)):

  • ? extends T <= ? extends S, если T <: S
  • ...
  • T <= ? extends T

мы можем использовать приведенные выше правила, чтобы доказать, что Number <= ?, поскольку Number <= ? extends Number <= ? extends Object= ?.

Ответ 3

В учебнике рассказывается о подстановочных знаках. Поэтому они хотят объяснить, когда и как вы должны их использовать. Когда вы читаете вперед, есть пример кода:

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number>  numList = intList;  // OK. List<? extends Integer> is a subtype of List<? extends Number>

Вы можете выполнить это назначение только в том случае, если ? является общим родителем Integer и Number. Я думаю, что в отношении с подстановочными знаками и дженериками можно сказать, что:

List<?> является общим родителем List<Number> и List<Integer>

потому что необходимо увидеть контекст учебника.

Ответ 4

Вот типы, которые имеют методы в Java с дженериками:

interface Collection<E> {
...
public boolean contains(Object o);
public boolean containsAll(Collection<?> c);
...
}

Первый метод вообще не использует generics! Второй метод - наш первый взгляд на важная аббревиатура. Тип Collection означает:

Collection<? extends Object>

Расширение объекта является одним из наиболее распространенных видов использования подстановочных знаков, поэтому имеет смысл предоставить короткую форму для ее написания.

Ответ 5

Вы смешиваете понятия наследования ООП или конкретные типы с одним из общих типов и отношений между этими генериками.

В одном из предложений в разделе "Подстановочные знаки и подтипы" говорится все:

Чтобы создать связь между этими классами... используйте верхний ограниченный шаблон

Для отношения типового типа ? является просто самым верхним, ограниченным от возможных подстановочных знаков ? extends <type> (верхний ограниченный шаблон), ? super <type> (нижний ограниченный подстановочный знак) и фактический type (точное совпадение или "верхний и нижний ограниченные подстановочные знаки" ).

Подстановочные знаки используются для того, чтобы обе концепции дженериков и ООП работали аккуратно друг с другом, но это не одно и то же. Проще говоря: List<?> является общим родителем List<Integer> и List<Number>, потому что отношение подстановочных знаков указано как таковое, что любой другой подстановочный шаблон создает отношение подтипа с ?. Это более или менее неформальное объяснение, посмотрите на ответ dejvuth для конкретных частей спецификации.