generic
TRANSCRIPT
![Page 2: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/2.jpg)
Что такое шаблоны?
Обобщённое программирование — это такой подход к описанию данных и алгоритмов, который позволяет их использовать с различными типами данных без изменения их описания. Generics (дженерики) или <<контейнеры типа T>> — подмножество обобщённого программирования.
![Page 3: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/3.jpg)
Обобщения (Generic)
Обобщения - это параметризованные типы. С их помощью можно объявлять классы, интерфейсы и методы, где тип данных указан в виде параметра.
Обобщения - добавили в язык java безопасность типов.
![Page 4: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/4.jpg)
![Page 5: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/5.jpg)
Пример реализации без шаблонов
class Box { private Object value; public Box(Object value) { this.value = value; } public Object get() { return value; }}
![Page 6: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/6.jpg)
Пример с шаблонным типом
class Box <E>{ private E value; public Box(E value) { this.value = value; } public E get() { return value; }}
![Page 7: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/7.jpg)
Синтаксис
После имени класса в угловых скобках "<" и ">" указано имя типа “E", которое может использоваться внутри класса.
Фактически E – это тип, который должен быть определён позже (при создании объекта класса).
![Page 8: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/8.jpg)
Правила именования типов
В именах переменных типа принято использовать заглавные буквы. Обычно для коллекций используется буква E, буквами K и V - типы ключей и значение (Key/Value), а буквой T (и при необходимости буквы S и U) - любой тип.
![Page 9: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/9.jpg)
Использование
Box<Tea> box1 = new Box<Tea>(new Tea());Tea tea = box1.get();
Box<Coffee> box 2 = new Box<Coffee> (new Coffee ());Coffee tea = box2.get();
![Page 10: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/10.jpg)
Алмазный синтаксис
Чтобы упростить жизнь программистам в Java 7 был введён алмазный синтаксис (diamond syntax), в котором можно опустить параметры типа. Т.е. можно предоставить компилятору определение типов при создании объекта. Вид упрощённого объявления:Pair<Integer, String> pair = new Pair<>(6, " Apr");
![Page 11: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/11.jpg)
Несовместимость generic-типов
Для того чтобы сохранить целостности и независимости друг от друга, у Generics существует так называемая "Несовместимость generic-типов".
List<Integer> li = new ArrayList<Integer>();List<Object> lo = li;lo.add(“hello”);
![Page 12: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/12.jpg)
Ограничения Generic
Невозможно создать объект generic типа, поскольку компилятор не знает, какой конструктор вызвать.
private static <T> T get(T value) { return new T(); }
![Page 13: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/13.jpg)
Ограничения Generic
Невозможно реализовывать одновременно два одинаковых интерфейса с разными типами.public class DecimalString implements Comparable<Number>, Comparable<String> {}
![Page 14: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/14.jpg)
Ограничения Generic
Невозможно объявить статическое поле generic типаpublic class MyClass<T> { private static T value; }
![Page 15: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/15.jpg)
Ограничения Generic
Невозможно использовать instatceof для параметризованного типа.
public static <E> void setList(List<E> list) { if (list instanceof ArrayList<Integer>) {} }
![Page 16: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/16.jpg)
Ограничения Generic
Невозможно создать массив параметризированного типа
Box<Tea>[] arrayOfLists = new Box<Tea>[2];
![Page 17: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/17.jpg)
Ограничения Generic
Невозможно перегрузить метод, в котором типы параметров “стираются” до одного и того же типа.public void print(Set<String> strSet) { }public void print(Set<Integer> intSet) { }
![Page 18: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/18.jpg)
Шаблоны аргументов (Wildcards )
Wildcard Parameters (wildcards). Этот термин в разных источниках переводится по-разному: метасимвольные аргументы, подстановочные символы, групповые символы, шаблоны, маски и т.д.
![Page 19: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/19.jpg)
Шаблоны аргументов (Wildcards )
Шаблон аргументов указывается символом ? и представляет собой неизвестный тип.Object obj = new Object(); Box<?> box3 = new Box<Object>(obj );
![Page 20: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/20.jpg)
Wildcards
Одно из преимуществ wildcards состоит в том, что они дают возможность написать код, который может оперировать различными generic-типами без знания их точных границ.
public void unbox(Box<?> box) { System.out.println(box.get()); }
![Page 21: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/21.jpg)
Wildcards
public void rebox(Box<?> box) { box.put(box.get()); }
![Page 22: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/22.jpg)
Wildcards
public void rebox(Box<?> box) { reboxHelper(box); } private<V> void reboxHelper(Box<V> box) { box.put(box.get()); }
![Page 23: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/23.jpg)
Wildcards
Вспомогательный метод reboxHelper() является generic-методом. Generic-методы вводят дополнительные параметры типов (помещаемые в угловые скобки перед типом возвращаемого значения), которые обычно используются для формулирования ограничений типов между параметрами и/или возвращаемым значением метода.
![Page 24: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/24.jpg)
Wildcards
Однако в случае reboxHelper() generic-метод не задействует параметр типа для определения ограничения типа, а позволяет компилятору – через вывод типа – дать имя параметру типа переменной box. Приём с capture-хелпером основан на выводе типов (type inference) и преобразовании при фиксации (capture conversion).
![Page 25: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/25.jpg)
Маски с ограничением extends
Box<? extends Coffee> box3 = new Box<Coffee>(new Coffee());
Box<? extends Tea> box3 = new Box<Tea>(new Tea());
![Page 26: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/26.jpg)
Маски с ограничением super
Box<? super Coffee> box3 = new Box<Coffee>(new Coffee());
![Page 27: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/27.jpg)
Универсальные методы (Generic methods)
По аналогии с универсальными классами (дженерик-классами), можно создавать универсальные методы (дженерик-методы), то есть методы, которые принимают общие типы параметров.
![Page 28: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/28.jpg)
Универсальные методы (Generic methods)
Универсальные методы не надо путать с методами в generic-классе. Универсальные методы удобны, когда одна и та же функциональность должна применяться к различным типам.
![Page 29: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/29.jpg)
Пример универсального метода
class Utilities { public static <T> void fill(List<T> list, T val) { for (int i = 0; i < list.size(); i++) list.set(i, val); } }
![Page 30: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/30.jpg)
Как это работает?
Поддержка generic-ов реализована средствами
компилятора. Виртуальная машина не предоставляет
никакой поддержки generic-ов, кроме возможности получения
информации о типах.
![Page 31: Generic](https://reader035.vdocuments.site/reader035/viewer/2022062900/58e49d401a28abf5428b56bf/html5/thumbnails/31.jpg)
Как это работает?
Во время компиляции generic-параметры
убираются, и, там, где это требуется, вместо них
вставляется приведение типов.