Дженерики Java (Generics) — это новая функция, представленная в JDK5, которая позволяет использовать параметры типа (параметр типа) при определении классов и интерфейсов. Объявленные параметры типа при использовании заменяются конкретными типами. Наиболее важное применение дженериков сейчас находится в новой структуре классов коллекций в JDK5, где используются Map и List. Преимущества очевидны: мы можем расширять больше классов по горизонтали. Недостатки на самом деле являются преимуществами, потому что, когда мы используем универсальные классы, мы должны очень четко понимать цель нашего кода и не можем использовать типы ошибок.
Самый простой общий класс
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e1;
/**
* Самый простой обобщенный класс, тип определяется самостоятельно
* @автор Гарин Чжан
*
* @param <T>
*/
общественный класс Point<T> {
частный Т вар;
общественный Т getVar() {
вернуть вар;
}
общественный недействительный setVar (T var) {
this.var = вар;
}
}
пакет com.garinzhang.javabase.generic.e1;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Point<String> p = новая точка<String> ();
p.setVar("кодер");
System.out.println(p.getVar());
}
}
Несколько универсальных типов
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e2;
/**
* Несколько общих типов. Как правило, лучше использовать буквы, близкие к T, например S, R и т. д.
* @автор Гарин Чжан
*
* @param <T>
* @парам <S>
*/
публичный класс Блокнот<T, S> {
личный Т-ключ;
частное значение S;
общественный T getKey () {
вернуть этот.ключ;
}
общественный S getValue () {
вернуть это.значение;
}
public void setKey (ключ T) {
this.key = ключ;
}
public void setValue (значение S) {
это.значение = значение;
}
}
пакет com.garinzhang.javabase.generic.e2;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Блокнот<String, Integer> p = новый Блокнот<String, Integer> ();
p.setKey("Кодер");
p.setValue(99999);
System.out.println("ключ: " + p.getKey());
System.out.println("значение: " + p.getValue());
}
}
Используйте подстановочный знак "?" в параметрах метода.
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e3;
/**
* Ключ к этому примеру находится в основном методе
* @автор Гарин Чжан
*
* @param <T>
*/
Информация о публичном классе<T> {
личный Т-ключ;
общественный T getKey () {
вернуть этот.ключ;
}
public void setKey (ключ T) {
this.key = ключ;
}
@Override
публичная строка toString() {
верните this.key.toString();
}
}
пакет com.garinzhang.javabase.generic.e3;
/**
* Используйте подстановочные знаки в параметрах метода.
* @автор Гарин Чжан
*
*/
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Info<String> я = новая информация<String>();
i.setKey("кодер");
весело (я);
Info<Integer> j = новый Info<Integer>();
j.setKey(9999);
весело (j);
}
public static void fun(Info<?> temp) {
System.out.println("Содержимое: " + temp);
}
}
Трансформация вверх не удалась
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e4;
/**
* Ключ к этому примеру находится в основном методе
* @автор Гарин Чжан
*
* @param <T>
*/
Информация о публичном классе<T> {
личный Т-ключ;
общественный T getKey () {
вернуть этот.ключ;
}
public void setKey (ключ T) {
this.key = ключ;
}
@Override
публичная строка toString() {
верните this.key.toString();
}
}
пакет com.garinzhang.javabase.generic.e4;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Info<String> strEg = новый Info<String>();
Info<Объект> objEg;
// Ошибка компиляции "Несоответствие типов: невозможно преобразовать из Info<String> в Info<Object>"
//Ошибка Upcast, String -> Object
// objEg = strEg;
}
}
Использование дженериков в интерфейсах
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e5;
/**
* Ключ к этому примеру находится в основном методе
* @автор Гарин Чжан
*
* @param <T>
*/
Информация об интерфейсе<T> {
общественный Т getVar();
}
пакет com.garinzhang.javabase.generic.e5;
/**
* Общий класс
* @автор Гарин Чжан
*
* @param <T>
*/
публичный класс InfoImpl<T> реализует Info<T> {
частный Т вар;
общественный InfoImpl (T var) {
this.setVar(вар);
}
общественный недействительный setVar (T var) {
this.var = вар;
}
общественный Т getVar() {
вернуть этот.var;
}
}
пакет com.garinzhang.javabase.generic.e5;
/**
* Необщий класс
* @автор Гарин Чжан
*
* @param <T>
*/
публичный класс InfoImpl1 реализует Info<String> {
частная строка var;
общественный InfoImpl1 (String var) {
this.setVar(вар);
}
общественный недействительный setVar (String var) {
this.var = вар;
}
общественная строка getVar() {
вернуть этот.var;
}
}
пакет com.garinzhang.javabase.generic.e5;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Info<String> strEg = новый InfoImpl<String>("кодер");
System.out.println("Содержимое: " + strEg.getVar());
Info<String> strEg1 = новый InfoImpl1("coder1");
System.out.println("Содержимое: " + strEg1.getVar());
}
}
Подстановочные знаки и использование расширений и супер
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e6;
/**
* Ключ к этому примеру находится в основном методе
* @автор Гарин Чжан
*
* @param <T>
*/
Информация о публичном классе<T> {
личный Т-ключ;
общественный T getKey () {
вернуть этот.ключ;
}
public void setKey (ключ T) {
this.key = ключ;
}
@Override
публичная строка toString() {
верните this.key.toString();
}
}
пакет com.garinzhang.javabase.generic.e6;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Info<String> strEg = новый Info<String>();
strEg.setKey("кодер");
//Ошибка компиляции "Метод fun(Info<? Extends Number>) в типе GenericExample неприменим для аргументов (Info<String>)"
// upTypeLimit(i);
// Используйте целочисленные или числовые типы.
Info<Integer> intEg = новый Info<Integer>();
intEg.setKey(9999);
upTypeLimit(intEg);
//Ошибка компиляции "Метод downTypeLimit(Info<? super String>) в типе GenericExample неприменим для аргументов (Info<Integer>)"
// downTypeLimit(intEg);
// Поскольку используется super, downTypeLimit может получать только саму строку и объект
// Проверены отношения наследования String, другие классы не наследуются, только Object
downTypeLimit (strEg);
Info<Object> objEg = новый Info<Object>();
objEg.setKey(999);
downTypeLimit (objEg);
}
/**
* <? расширяет T> представляет верхнюю границу типа, указывая, что параметризованный тип может быть T или подклассом T
* @парам темп.
*/
public static void upTypeLimit(Info<? Extends Number> temp) {
System.out.println("Содержимое: " + temp);
}
/**
* <? super T> представляет нижнюю границу типа (называемую квалификацией супертипа в Java Core), указывая, что параметризованный тип является супертипом (родительским типом) этого типа до тех пор, пока Object
* В этом примере это означает, что T может быть только Object или String, поскольку String наследуется только от Object.
* @парам темп.
*/
public static void downTypeLimit(Info<? super String> temp) {
System.out.println("Содержимое: " + temp);
}
}
Обобщенные методы, несколько обобщенных методов в методе
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e7;
/**
* Обобщенные методы, несколько обобщенных методов в методе.
* @автор Гарин Чжан
*
* @param <T>
*/
Информация о публичном классе {
/**
* Формат: модификация метода <список типов, разделенных запятыми> тип возвращаемого значения имя метода (список параметров)
* Например: public <T, S> T fun(T t, S s)
* @парам т
* @парам с
* @возвращаться
*/
public <T, S> T fun(T t, S s) {
System.out.println(s.toString());
вернуть т;
}
}
пакет com.garinzhang.javabase.generic.e7;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Информация информация = новая информация();
String str = info.fun("coder", "распечатать второй общий параметр");
System.out.println(str);
int i = info.fun(30, "напечатайте второй параметр еще раз");
System.out.println(я);
}
}
Универсальный тип, передаваемый или возвращаемый в методе, определяется типом параметра, установленным при вызове метода.
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e8;
/**
* расширяется
* @автор Гарин Чжан
*
* @param <T>
*/
общественный класс Info<T расширяет номер> {
частный Т вар;
общественный Т getVar () {
вернуть этот.var;
}
общественный недействительный setVar (T var) {
this.var = вар;
}
@Override
публичная строка toString() {
вернуть this.var.toString();
}
}
пакет com.garinzhang.javabase.generic.e8;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Info<Integer> intEg = fun(30); // Тип здесь определен как Integer.
System.out.println(intEg.getVar());
}
/**
* Универсальный тип, передаваемый или возвращаемый в методе, определяется типом параметра, установленным при вызове метода.
* параметр @param
* @возвращаться
*/
public static <T расширяет номер> Info<T> fun(T param) {
Info<T> temp = новый Info<T>();
temp.setVar(параметр);
температура возврата;
}
}
Сделайте два типа параметров, передаваемых в методе, согласованными.
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e9;
/**
* Посмотреть главную
* @автор Гарин Чжан
*
* @param <T>
*/
Информация о публичном классе<T> {
частный Т вар;
общественный Т getVar () {
вернуть этот.var;
}
общественный недействительный setVar (T var) {
this.var = вар;
}
@Override
публичная строка toString() {
вернуть this.var.toString();
}
}
пакет com.garinzhang.javabase.generic.e9;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Info<String> i1 = новая информация<String>();
i1.setVar("Привет");
Info<String> i2 = новая информация<String>();
i2.setVar("Кодер");
Info<Integer> i3 = новый Info<Integer>();
i3.setVar(999);
добавить (я1, я2);
//Ошибка компиляции "Метод add(Info<T>, Info<T>) в типе GenericExample неприменим для аргументов (Info<String>, Info<Integer>)"
// добавить(i1, i3);
}
/**
* Два типа параметров, передаваемых в методе, должны быть согласованными.
* параметр @param
* @возвращаться
*/
public static <T> void add(Info<T> i1, Info<T> i2) {
System.out.println(i1.getVar() + ":" + i2.getVar());
}
}
Обобщения, переменные параметры, аналогичные объекту Arguments в JavaScript.
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e10;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Целое число i[] = fun(1, 2, 3, 4, 5, 6);
fun2 (я);
}
public static <T> T[] fun(T... arg) {
вернуть аргумент;
}
public static <T> void fun2(T param[]) {
System.out.println("Общий массив: ");
for(T t : param) {
System.out.println(t + ",");
}
}
}
Универсальная вложенность: используйте универсальные классы в качестве параметров, чтобы определить возвращаемое значение на основе типа возвращаемого значения;
Скопируйте код кода следующим образом:
пакет com.garinzhang.javabase.generic.e11;
/**
* Принимает два общих типа
* @автор Гарин Чжан
*
* @param <T>
*/
общественный класс Info<T, V> {
частный Т вар;
личное значение V;
общественный Т getVar() {
вернуть этот.var;
}
общественный недействительный setVar (T var) {
this.var = вар;
}
общественный V getValue () {
вернуть это.значение;
}
public void setValue (значение V) {
это.значение = значение;
}
@Override
публичная строка toString() {
вернуть this.var.toString();
}
}
пакет com.garinzhang.javabase.generic.e11;
/**
* Принимает 1 общий тип
* @автор Гарин Чжан
*
* @param <T>
*/
публичный класс Demo<S> {
личная информация S;
общедоступная демо-версия (информация S) {
this.setInfo(информация);
}
общественная недействительность setInfo (S информация) {
this.info = информация;
}
общественный S getInfo () {
вернуть this.info;
}
}
пакет com.garinzhang.javabase.generic.e11;
импортировать java.util.List;
импортировать com.google.common.collect.Lists;
общественный класс GenericExample {
/**
* @param аргументы
*/
public static void main(String[] args) {
Demo<Info<String, Integer>> d;
Info<String, Integer> я;
я = новая информация<String, Integer>();
i.setVar("Кодер");
я.setValue(999);
d = новый Demo<Info<String,Integer>>(i);
System.out.println("Содержимое: " + d.getInfo().getVar());
System.out.println("Содержимое: " + d.getInfo().getValue());
System.out.println(query(1, 2, 3, 4, 5).toString()); // [1, 2, 3, 4, 5]
// Предупреждение «Безопасность типов: для параметра varargs создается общий массив Object&Comparable<?>&Serializable»
System.out.println(query(1, 2, 3, "StringType").toString()); // [1, 2, 3, StringType]
System.out.println(query("I", "am", "a", "coder").toString());// [I , am , a , coder]
List<String> list = Lists.newArrayList("Я", "я", "а", "кодер");
System.out.println(list.toString()); // [Я, программист]
}
/**
* Определите универсальный тип через возвращаемое значение. Тип возвращаемого значения в этом методе автоматически генерируется определением метода.
* Элементы @param
* @возвращаться
*/
public static <E> List<E> query(E... elements) {
// https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16.
//импортируем com.google.common.collect.Lists;
// <зависимость>
// <groupId>com.google.guava</groupId>
// <artifactId>гуава</artifactId>
// <версия>16.0.1</версия>
// </зависимость>
вернуть Lists.newArrayList(elements);
}
}