Привет всем, я Сяо Цай, Сяо Цай, который хочет быть Цай Буцаем в интернет-индустрии. Она может быть мягкой или жесткой, как она мягкая, а белая проституция жесткая!Черт~ Не забудьте поставить мне тройку после прочтения!
Эта статья в основном знакомит
Java中泛型的使用
При необходимости вы можете обратиться к
Если это поможет, не забудьтеподобно❥
Официальный аккаунт WeChat открыт,Хорошая еда, студенты, которые не обратили внимания, не забудьте обратить внимание!
Поскольку мы говорили о дженериках выше, давайте снова рассмотрим дженерики в этой статье!
Сначала, первый смысл гель
До появления дженериков мы обычно использовали тип какObjectобъект элемента. Например, мы можем построить типObjectВ коллекции могут храниться объекты любого типа данных, но когда мы вынимаем элементы из коллекции, нам нужно четко знать тип данных каждого сохраняемого элемента, чтобы можно было выполнить преобразование элементов, иначе будутClassCastException
аномальный.
1. Что такое дженерики
Дженерики находятся вJava1.5Новая функция, представленная позже, которая обеспечивает механизм контроля безопасности типов во время компиляции, который позволяет нам обнаруживать структуры данных недопустимых типов во время компиляции.
Суть его в параметризованном типе, то есть в качестве параметра указывается тип данных, с которым нужно манипулировать. Этот тип параметра можно использовать вКлассы, интерфейсы и методы, соответственно называетсяОбщие классы, общие интерфейсы и общие методы
2. Используйте преимущества
- безопасность типа
При наличии дженериковПока нет предупреждений во время компиляции, исключений ClassCastException во время выполнения нет..
- Устранение бросков
Мы можем получить элементы из универсальной коллекции без преобразования типов.
- более читаемый
Вы можете напрямую увидеть, какие элементы типа данных хранятся в коллекции.
Использование дженериков
1. Сценарии использования
1) Общий класс
базовая грамматика
class 类名称 <泛型标识,泛型标识,…> {
private 泛型标识 变量名;
.....
}
Пример использования
class Result<T>{
private T data;
}
Примечание:
- После Java 1.7 можно выполнять вывод типов, а определенные типы данных в можно опускать или не записывать:
类名<具体的数据类型> 对象名 = new 类名<>();
- Если мы не используем его, когда мы его используем
<>
чтобы сформулировать тип данных, то тип операцииObject
- Типовые параметры в универсальном могут быть только
类
тип, а не примитивный тип данных, такой какint,double,float...
- Когда мы передаем разные типы данных для создания объектов, это логически можно рассматривать как несколько разных типов данных, но на самом деле все они одного типа.
Выше приведено простое использование универсальных классов.Какой тип мы хотим использовать, мы указываем тип при его создании, и когда мы его используем, класс будет автоматически преобразован в тип, который хочет использовать пользователь.
Затем, если мы определим универсальный класс без объявления типа данных при построении объекта, по умолчанию будетObject
Тип, время, затраченное на преобразование типа данных, требуется:
Result objectRes = new Result("testObejct");
String str = (String) objectRes.getData();
System.out.println(str);
правило:
- Подкласс также является универсальным классом, тогда универсальный тип подкласса и суперкласса должен быть одинаковым.
public class ResultChild<T> extends Result<T> {}
- Подкласс не является универсальным классом, тогда родительский класс должен указать тип данных
public class ResultChild extends Result<String> {}
2) Общий интерфейс
базовая грамматика
public 接口名称 <泛型标识, 泛型标识, ...>{
泛型标识 方法名();
...
}
Пример использования
public interface ResultInterface<T> {
T getData();
}
Общие интерфейсы, такие как общие классы, имеют следующие правила:
- Класс реализации не является универсальным классом, и интерфейс должен иметь четкий тип данных.
- Класс реализации также является универсальным классом, а универсальный тип класса реализации и интерфейса должны быть согласованы.
3) Общий метод
существуетJavaВ , определения универсальных классов и универсальных интерфейсов относительно просты, нообщий методЭто сложнее.
- Универсальный класс — это конкретный тип, указанный в универсальном классе, который создается, когда
- Общий метод заключается в указании конкретного типа универсального при вызове метода.
базовая грамматика
修饰符 <T, E, ...> 返回值类型 方法名(形参列表){}
-
между модификаторами и возвращаемым типом
<T>
Используется для объявления этого метода как универсального метода. -
только объявлено
<T>
Метод представляет собой универсальный метод, даже если общий класс в типе возвращаемого значения использует универсальный метод элемента, он не является универсальным методом -
<T>
Указывает, что метод будет использовать универсальный тип T, только тогда может использоваться универсальный тип T в способе
Пример использования
private <T> Result<T> getResult(T data) {
return new Result<T>(data);
}
Общие методы с переменными параметрами:
private <T> void printData(T... data) {
for (T t : data) {
System.out.println(t);
}
}
Примечание:
- Общие методы позволяют методам изменяться независимо от класса
- еслистатическийМетод Чтобы использовать универсальные возможности, вы должны сделать его универсальным методом.
2. Введите подстановочные знаки
1) Что такое подстановочный знак типа
- Подстановочные знаки типа обычно используются" ? "Замените конкретные типы аргументов
- Подстановочные знаки типаТип аргумента, вместотип параметра
Подстановочные знаки типа далее делятся наверхний предел подстановочных знаков типаа такженижняя граница подстановочных знаков типов
2) Базовая грамматика
верхний предел подстановочных знаков типа:
类/接口<? extends 实参类型>
Примечание. Тип универсального типа должен быть только фактическим типом параметра или типом фактического типа параметра.ПодклассТипы
Нижняя граница для подстановочных знаков типа:
类/接口<? super 实参类型>
Примечание. Тип универсального типа должен быть только фактическим типом параметра или фактическим типом параметра.отецТипы
2) Пример использования
верхний предел подстановочных знаков типа:
Если бы мы напечаталиListзначение, мы могли бы сделать:
private void printData(List list) {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
Выглядит хорошо, но ощущения странные. Потому что это как черный ящик, я этого не знаюListКакой тип параметров внутри. Затем мы определяем тип при прохождении параметров:
private void printData(List<Object> list) {
for (Object o : list) {
System.out.println(o);
}
}
Но это определение слишком широкое.ObjectЭто родительский класс всех типов.Если я хочу, чтобы этот метод работал только с элементами числового типа, я могу использовать еговерхний предел подстановочных знаков типаДля решения этой проблемы:
private void printData(List<? extends Number> numList) {
for (Number number : numList) {
System.out.println(number);
}
}
Но когда нам нужно использовать этот метод, мы можем интуитивно увидеть, что фактические параметры, передаваемые этим методом, могут быть толькоNumberподкласс .
printData(Arrays.asList(1, 2, 3));
printData(Arrays.asList(1L, 2L, 3L));
нижняя граница подстановочных знаков типов:
Выше мы узналиИспользование заглавных букв подстановочных знаков,ТакВведите подстановочный знакКак это используется?
Введите подстановочный знакЧастоты, используемые в нашем развитии в мирное время, относительно невелики. Компилятор знает только элемент сбора - это нижний предел родительского типа, но в частности, какой тип родительского типа неопределен. Таким образом, взятые из набора элементов можно рассматривать какObjectОбработка типов (компилятор не может определить, какой объект родительского класса извлекается).
Мы можем настроить функцию, которая копирует коллекцию:
- Сначала определите два класса:
public class Animal {
}
public class Pig extends Animal{
}
- Определите функцию копирования:
private static <T> Collection<? super T> copy(Collection<? super T> parent, Collection<T> child) {
for (T t : child) {
parent.add(t);
}
return parent;
}
- использовать:
List<Animal> animals = new ArrayList<>();
List<Pig> pigs = new ArrayList<>();
pigs.add(new Pig());
pigs.add(new Pig());
copy(animals,pigs);
System.out.println(animals);
3. Введите стирание
Поскольку общая информация существует только на этапе компиляции кода, поэтому вводJVMРаньше информация о дженериках стиралась, что называетсястирание типа
1) Неограниченное стирание типов
Перед стиранием типа:
public class Result<T>{
private T data;
}
После стирания типа:
public class Result{
private Object data;
}
2) Удаление ограниченного типа
Перед стиранием типа:
public class Result<T extends Number>{
private T data;
}
После стирания типа:
public class Result{
private Number data;
}
3) Стереть параметры определения типа в методе
Перед стиранием типа:
private <T extends Number> T getValue(T value){
return value;
}
После стирания типа:
private Number getValue(Number value){
return value;
}
END
Знакомство с дженериками подходит к концу.В этой статье мы познакомимся со сценариями использования дженериков, подстановочными знаками и стиранием типов. Контента не так много, но приятного просмотра! Дорога длинная, Сяокай будет искать ее вместе с вами!
Если вы будете усердно работать сегодня, завтра вы сможете сказать на одну вещь меньше, чтобы попросить о помощи!
Я Сяо Цай, человек, который учится у вас.
💋
Официальный аккаунт WeChat открыт,Хорошая еда, студенты, которые не обратили внимания, не забудьте обратить внимание!