Почему нельзя ковариантно писать на Java?

У меня такой код:

class Scratch {
    public static void main(String[] args) {
        List<Cat> cats = new ArrayList<>();

        List<? extends Animal> animals = cats;

        animals.add(new Cat()); // compile error

        Animal animal = animals.get(0);
    }
}

class Animal {

}

class Cat extends Animal {

}

class Dog extends Animal {

}

Почему нельзя добавить экземпляр Cat к животным? Добавьте экземпляр Cat или Dog к животным и прочтите элементы, поскольку животные безопасны по типу. Я знаю PECS (сокращение от «Producer extends и Consumer super»), но я не могу понять, почему я не могу писать в ковариации и не могу читать в Java.

PECS. stackoverflow.com/q/2723397/2970947

Elliott Frisch 11.08.2018 06:29

Вы можете захотеть прочтите это в первую очередь.

Edwin Dalorzo 11.08.2018 06:30

Что, если бы вместо new Cat() вы добавили животным new Dog()? Что бы сделал Cat c = cats.get(0)?

yshavit 11.08.2018 06:30
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
57
1

Ответы 1

<? extends Animal> не является Cat, это может быть любой подкласс Animal, например:

List<? extends Animal> dogs = new ArrayList<Dog>();
dogs.add(new Cat()); // compile error

Независимо от того, какой на самом деле тип <? extends Aminal>, он не может добавить какой-либо подкласс Animal. Используйте List<Animal> вместо List<? extends Animal>.

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