Нижняя граница java generic wildcard: список <? супер отец> список = новый список массивов <> ()

почему это работает? Я понял, что "? Super Father" разрешает только папу и дедушку

введите описание изображения здесь

Код здесь -------------------

public class RxTest {

public static void main(String[] args) {


    // extends -> read only
    // super -> write only

    List<? super Father> list = new ArrayList<>();

    list.add(new Child());
    list.add(new Child());

    System.out.println(list.size()); // 2

    // why does it work? I understood taht "? super Father" only allows Father and GrandFather


}

}

class GrandFather { }

class Father extends GrandFather { }

class Child extends Father { }

Возможный дубликат Разница между <? super T> и <? расширяет T> в Java

faris 10.09.2018 07:40

Разместите код в своем вопросе вместо того, чтобы прикреплять его как изображение

faris 10.09.2018 07:43

Хм .. Я думаю, это сводится к List <Object>?

keuleJ 10.09.2018 08:09

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

Andy Turner 10.09.2018 08:26

Между прочим, super - это граница ниже, а не верхняя граница, как указано в заголовке.

Andy Turner 10.09.2018 08:33
2
5
69
1

Ответы 1

Не читайте «? super Father» как «все является супертипом Father».

Прочтите это как «ожидаемый тип элементов в этом списке - это супертип Father». Может показаться, что я говорю то же самое, но это не то же самое.

Он говорит о том, что объект, создавший список действительный (а не ссылку с подстановочными знаками), ожидает, что все в списке будет относиться к определенному типу, и этот тип является супертипом Father. Вы не можете создать new ArrayList<? super/extends Something>, это должен быть new ArrayList<Something>.

Таким образом, вы можете добавлять экземпляры Father (который включает подтипы, такие как Child), не нарушая ожиданий в отношении элементов в списке.

Помните PECS:

Producer extends, Consumer super

List<? super Father> - это потребитель экземпляров Father.

Это нет то же самое, что и "super -> write only", как в вашем коде. Вы все еще можете читать из списков с нижним ограничением, вам просто нужно рассматривать все как Object.

Точно так же extends не означает «только для чтения»: вы можете добавлять существующие элементы из списка в себя, а также добавлять буквальный null.

«Точно так же extends не означает« только для чтения »: вы можете добавлять существующие элементы из списка в себя», только если вы записываете подстановочный знак в переменную типа. Он не будет работать только с подстановочным знаком.

newacct 10.09.2018 19:26

@newacct да, но вы можете передать список с подстановочными знаками в метод, который фиксирует переменную типа, поэтому список с подстановочными знаками в методе не защищает от записи в сам себя.

Andy Turner 10.09.2018 19:33

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