Часто возникают ситуации, когда в Java нужно работать с коллекциями объектов, которые являются наследниками или предками определенного класса. Например, может быть коллекция объектов класса Animal, а также его наследников Cat и Dog. В Java для этого используются обозначения и .
используется, когда нужно получить объекты из коллекции, которые являются экземплярами класса T или его подклассами. Например, если есть коллекция объектов класса Animal, то можно получить из нее объекты класса Cat, если Cat является подклассом Animal. Однако добавить в такую коллекцию новые объекты нельзя, потому что компилятор не сможет гарантировать, что они будут правильного типа.
List<? extends Animal> animals = new ArrayList<Cat>(); // можно получить объект из коллекции Animal animal = animals.get(0); // но добавить объект в коллекцию нельзя animals.add(new Cat()); // ошибка компиляции
наоборот, используется, когда нужно добавить в коллекцию новые объекты, которые являются экземплярами класса T или его подклассами. Например, если есть коллекция объектов класса Animal, то в нее можно добавить объекты класса Cat. Однако получить объект из такой коллекции можно только с типом Object (без явного приведения типов), потому что компилятор не может гарантировать, какого конкретно подтипа будет объект.
List<? super Animal> animals = new ArrayList<Animal>(); // можно добавить объект в коллекцию animals.add(new Cat()); // но получить объект из коллекции можно только как Object Object object = animals.get(0);
Таким образом, и позволяют гибко работать с коллекциями объектов, учитывая их иерархию наследования. Но при этом важно помнить ограничения каждого из этих подходов.
Добавить комментарий