В чем разница между списком<номер> и списком<? расширяет номер>?
У меня есть очень простой вопрос, связанный с дженериками 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>
-> Список Number
s (или случаи Number
)
List<? extends Number>
-> Список любого типа, который расширяется Number