7. Generics (Обобщение) Flashcards
Что такое Generics в Java?
Generics - это параметризованные типы. При определении переменной данного класса и создании объекта после имени класса в угловых скобках нужно указать, какой именно тип будет использоваться вместо универсального параметра. Параметров может быть сколько угодно. Обозначаются любой буквой или набором символов.
При этом надо учитывать, что они работают только с объектами, но не работают с примитивными типами.
Где мы можем использовать generics?
С их помощью можно объявлять классы (для того чтобы использовать класс как Generics, мы должны прописать после имени класса , куда можно подставить любое имя или wildcard), интерфейсы и методы (особенностью обобщенного метода является использование универсального параметра в объявлении метода после всех модификаторов и перед типом возвращаемого значения, при вызове подобного метода перед его именем в угловых скобках указывается, какой тип будет передаваться на место универсального параметра:), где тип данных указан в виде параметра, которые автоматически будут работать с различными типами данных. Так же могут быть обобщенные конструкторы. В этом случае перед конструктором также указываются в угловых скобках универсальные параметры
Что такое ограничение типов?
Ограничения позволяют указать базовый класс, которому должен соответствовать параметр.
Для установки ограничения после универсального параметра ставится слово extends, после которого указывается базовый класс ограничения
extends Number - ограничивает возможность приведения типов, все вызываемые объекты должны имплементировать или быть наследниками класса которым ограничен дженерик (должны быть ниже по иерархии классов)
(T extends ClassName & InterfaceName) - сначала класс, затем интерфейсы.
То есть на место параметра T мы можем передать либо класс ClassName, либо один из его классов-наследников и которые реализуют интерфейс InterfaceName.
При этом важно понимать, что поскольку мы установили подобное ограничение, то компилятор будет распознавать объекты типа T как объекты типа ClassName. И в этом случае мы можем вызывать у объектов типа T методы класса ClassName. И мы бы не смогли бы это сделать, если бы мы не задали подобного ограничения.
В качестве ограничений могут выступать и другие обобщения, которые сами могут иметь ограничения:
Что такое wildcard и зачем он нужен?
wildcard используется, когда нам не важен параметр входящего типа, но его нужно определить, чтобы все элементы списка были однотипные. обозначается как “?”
Обобщённые типы в Java инвариантны, поскольку вместо создания универсального метода, работающего с Object’ами, можно его параметризовать, превратив в обобщённый метод и сохранив контроль типов.
Вместе с тем в Java можно реализовать своего рода ко- и контравариантность обобщенных типов, используя символ-джокер и уточняющие спецификаторы: List extends Animal> будет ковариантен подставляемому типу, а List super Animal> — контравариантен.
Можно ли ограничить Wildcard?
Wildcard также можно ограничивать
extends Number или super
Что произойдет при перегрузке метода с разными дженериками?
все джерики превращаются в Object
T ==> Object ==> String
Что происходит с дженериками при компиляции?
Компилятор удаляет всю информацию по generics, проставляя необходимы приведения типов.
если T приводим к String
то при компиляции
типы приводятся как:
T ==> Object ==> String
Дженерики существуют только до этапа компиляции, после него они удаляются и переходят в вид с явным приведением типов
Что создано для совместимости версий старых jdk
Raw type - это дженерик, использованный без указания типов; в данном случае raw type - это Gen, который вы создаете как просто Gen. Т.к. вы не указываете тип, компилятор обрабатывает этот класс по-другому, “сбрасывая” всю generic-информацию, которую может найти