Использование ‘? расширяет ‘и’? супер ‘в compilationе generics

Может ли кто-нибудь объяснить, почему мы используем ? в Collection дженериках.

Как например:

  List numberlist; List numberlist; 

Подстановочные знаки вводят ограничения в том, как можно использовать коллекцию.

Например, со List List , я не могу добавить в список новые элементы. Это потому, что все, что я знаю, это то, что список является своего рода подтипом Number , но я не знаю, что это за реальный подтип (так как я мог знать, что добавить?). Например, возьмите следующий код:

 public void doSomethingWith(List numbers) { numbers.add(Integer.valueOf(0)); // Won't compile } 

Это не будет компилироваться, потому что оба этих вызова метода являются законными:

 doSomethingWith(new ArrayList()); doSomethingWith(new ArrayList()); 

Что вы можете сделать, так это прочитать элементы из списка:

 // This will all compile public void doSomethingWith(List numbers) { for (Number number : numbers) { // Do something with number } // OR Number number = numbers.get(0); // OR Number number = numbers.remove(0); } 

Звонки на такие методы, как get , возвращают какой-то Number , мы знаем, что для факта из-за ? extends Number ? extends Number , поэтому мы можем рассматривать его так же, как и для чтения.

С другой стороны, List List имеет совершенно противоположный результат. Я больше не могу читать из списка, но могу писать. Я это знаю ? это, безусловно, будет суперclass Integer , поэтому конкретные типы списка определенно будут принимать значения Integer . Например:

 public void doSomethingWith(List integers) { integers.add(Integer.valueOf(0)); } 

Этот код является полностью законным. Однако, если вы хотите прочитать из списка, единственный способ сделать это – использовать Object поскольку для чего-то еще требуется кастинг (который требует знания его конкретного типа):

 for (Object obj : integers) // OR Object obj = integers.get(0); // OR Object obj = integers.remove(0); 

Что действительно происходит

Вот что происходит на самом деле. Когда вы укажете ? extends Number ? extends Number , вы делаете любой метод, который принимает элементы как неприменимый параметр. На самом деле, если вы пытаетесь автозаполнять код в Eclipse, используя Ctrl + Space в List List , он показывает null как типы параметров в методах add и тому подобное. Между тем, все методы, возвращающие элементы, гарантированно возвращают хотя бы какой-то Number , хотя вы не будете точно знать, какой из подclassов Number это действительно может быть.

Когда вы укажете ? super Integer ? super Integer , вы производите любой метод, который принимает элементы как параметр, гарантирующий, что они будут принимать значения Integer (и подclassы Integer ). Это позволяет вам вызывать методы типа add поскольку вы знаете, что они будут принимать типы Integer . Тем не менее, все методы, возвращающие элементы, гарантируют только что-то вернуть, но мы не знаем, что, поэтому все методы, возвращающие элементы, гарантируют возврат Object .

PECS – отличный аббревиатура, чтобы запомнить это, это означает « P roducer E xtends, C onsumer S upers». Это означает, что если вы хотите, чтобы ваш список дал вам что-то, это продюсер, и вы должны использовать extends . Если вы хотите, чтобы ваш список принимал вещи от вас, это потребитель, поэтому вы используете super . См. Этот ответ для получения дополнительной информации.

Но что, если у меня есть подстановочный знак без ограничений?

Он делает оба! ограничивает вас от вызова методов, которые принимают общий тип в качестве аргумента и вызывает все методы, возвращающие общий тип для возврата Object . Это потому, что мы понятия не имеем, что такое тип. Например, все эти назначения в List Являются законными:

 List list; list = new ArrayList(); list = new ArrayList(); list = new ArrayList(); 

И так далее.

Это подстановочный знак. ? означает, что любой class, который наследует от числа или является суперclassом classа Integer, будет работать. Надеюсь это поможет. 🙂

Когда вы изучаете подстановочные знаки и разницу между extends и super , просто помните PECS . Это правило имеет все в нем с большой простотой, чтобы помнить.

? используется для определения диких карт при использовании дженериков.

Вышеприведенный оператор говорит, что List принимает любой объект типа Number

? означает любой class, поэтому

 ? extends MyClass 

означает любой подclass MyClass или MyClass.

Вот что я сказал бы:

 List numberlist; //Any class that is extended from Number class, for example Integer, BigInt, ... may come List numberlist; //Any class that Integer class is extended from. Here for example Number may come 

потому как:

 Integer extends Number{ } 

List List и List оба позволяли бы добавлять, например, целые числа, но: С помощью List вы могли бы ввести туда Целые числа и все остальное, что «есть» Число. Со List List вы можете добавить туда только один конкретный тип runtimetype. Будь то Integer, тогда вы не можете добавить другой тип, который также является числом.

  • Как наиболее элегантно перебирать параллельные коллекции?
  • Интерфейс коллекции против массивов
  • Как сортировать аррайалист объектов по свойству?
  • Пересечение java.util.Map
  • В чем разница между Collection.stream (). ForEach () и Collection.forEach ()?
  • Итерация над compilationами Java в Scala
  • Коллекция и List , что вы должны использовать на своих интерфейсах?
  • Как отсортировать ArrayList, используя несколько критериев сортировки?
  • Максимальный размер HashSet, Vector, LinkedList
  • C # Сортировка коллекции, которая позволяет дублировать ключи
  • Как я могу инициализировать ArrayList со всеми нулями в Java?
  • Давайте будем гением компьютера.