В чем разница между списком<номер> и списком<? расширяет номер>?

У меня есть очень простой вопрос, связанный с дженериками Java. Я думал, что оба List<Number> а также List<? extends Number> однородны. Я прав или есть что-то фундаментальное, чего мне не хватает?

3 ответа

Решение

Родовые типы более педантичны.

<? extends Number> означает номер или неизвестный подкласс. Если вы получите такое значение, это будет Number, но вы не можете дать значение этого типа, потому что вы не знаете, какой из них действителен.

Разница в аргументах и ​​возвращаемых значениях.

List<Number> numbers = new ArrayList<Number>();
Number n = 1;
numbers.add(n); // ok.
n = numbers.get(0); // ok
numbers.add(1); // ok.

List<? extends Number> numbers2 = new ArrayList<Double>();
numbers2.add(n); // not ok
n = numbers2.get(0); // ok

List<? super Number> numbers3 = new ArrayList<Serializable>();
numbers3.add(n); // ok
n = numbers3.get(0); // not ok.

super используется в нескольких местах, чтобы показать, что тип может быть супер типом. например

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

public static <T> void sort(List<T> list, Comparator<? super T> c)

Это означает, что вы можете иметь

Comparator<Number> comparesAnyNumbers = ...
List<Integer> ints = ...
Collections.sort(ints, comparesAnyNumbers);

Обобщения являются языковыми функциями времени компиляции, то есть они не существуют во время выполнения. В универсальном механизме для проверок во время компиляции они не являются однородными, т.е. если вы хотите использовать полиморфизм в универсальном типе.

Следующее дает вам ошибку времени компиляции, хотя это кажется верным определением:

 List<Number> list = new ArrayList <Integer>();

в то время как

 List<? extends Number> list = new ArrayList <Integer>();

является действительным. Кроме того, вы не можете использовать подстановочные знаки справа:

 List list = new ArrayList <? extends Integer>();

не будет скомпилировано

List<Number> -> Список Numbers (или случаи Number)

List<? extends Number> -> Список любого типа, который расширяется Number

Другие вопросы по тегам