«Эта статья участвовала в мероприятии Haowen Convocation Order, щелкните, чтобы просмотреть:Двойные заявки на внутреннюю и внешнюю стороны, призовой фонд в 20 000 юаней ждет вас, чтобы бросить вызов!"
Хотя я некоторое время писал код на Java, пока я вижу дженерики, я все равно предпочитаю сдаться. Но сегодня я просматривал код начальника компании и обнаружил, что дженерики используются во многих местах, поэтому сегодня я разберусь с дженериками, в которых разбираюсь.
что такое дженерики
Общее программирование — это стиль или парадигма языков программирования. Обобщения позволяют программистам, пишущим код на строго типизированных языках программирования, использовать типы, указанные позже, указывая эти типы в качестве параметров во время создания экземпляра. Существует два основных типа определений: 1⃣️ Некоторые типы, которые содержат параметры типа в программном кодировании, то есть общие параметры могут представлять только классы, а не отдельные объекты. 2⃣️ Некоторые классы, содержащие параметры в кодировке программы. Его параметры могут представлять классы или объекты и т. д.
👆Объяснение выше взято из энциклопедии Baidu.Проще говоря, дженерики — это парадигма кода.
Дженерики Java
Параметры дженериков Java могут представлять только классы, а не отдельные объекты. Поскольку фактический тип параметра типа универсального типа Java исключается во время компиляции, тип его параметра типа не может быть известен во время выполнения, и невозможно напрямую использовать тип примитивного значения в качестве параметра универсального типа.
Принципы проектирования дженериков Java:
Отложите специфичность типа до создания объекта или вызова метода для определенного типа. Пока нет предупреждений во время компиляции, то нет и во время выполненияClassCastException
аномальный.
Вот пример простых дженериков:
public class Generic {
public static void main(String[] args) {
// C 可以接受 String
C<String> stringC = new C<>("Hello world");
System.out.println(stringC);
// C 可以接受 Integer
C<Integer> integerC = new C<>(100);
System.out.println(integerC);
}
}
// C 可以接受任意类型数据的初始化
class C<T> {
private T item;
public C(T t){
item = t;
}
@Override
public String toString() {
return item + "";
}
}
Т, Е, К, В
T, E, K, V по сути являются подстановочными знаками. Кодирование иногда связано с соглашением. Например, мы можем использовать любую букву между A-Z для обозначения подстановочных знаков, и это не повлияет на нормальную работу программы. Обычно T, E, K, V согласовываются следующим образом:
-
?
Представляет неопределенный тип Java -
T ( type )
Представляет конкретный тип Java -
K V ( key value )
Представляет значение ключа в значении ключа Java. -
E ( element )
означает Элемент
подстановочный знак
-
подстановочный знак верхней границы
? extends T
Например
List< ? extends Number>
Цель состоит в том, чтобы принятьList<Integer> or List<Long>
тип данных. -
Подстановочный знак Нижнего мира
? super T
Например
List<? super Number>
Цель состоит в том, чтобы восполнить недостаток, заключающийся в том, что может храниться только один конкретный тип данных.
public class Generic {
public static void main(String[] args) {
// 可以
List<? super Number> list = new ArrayList<>();
list.add(10);
list.add(20L);
list.add(20.2);
System.out.println(list);
List<Integer> list1 = new ArrayList<>();
List<Long> list2 = new ArrayList<>();
list1.add(10);
list1.add(20);
list2.add(10L);
list2.add(20L);
read(list1);
read(list2);
}
private static void read(List< ? extends Number> list) {
Number first = list.get(0);
Number last = list.get(list.size() - 1);
System.out.println("first = " + first.toString() + " last = " + last.toString());
}
}
Наконец, взгляните на принцип PECS (Producer Extends Consumer Super):
- Если вы часто читаете контент, целесообразно использовать расширение верхней границы.
- Часто вставляется в него, подходит для использования Nether Super
Общий случай
// 多参数泛型
class Person<N, A, S> {
private N name;
private A age;
private S sex;
Person(N name, A age, S sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public N getName() {
return name;
}
public void setName(N name) {
this.name = name;
}
public A getAge() {
return age;
}
public void setAge(A age) {
this.age = age;
}
public S getSex() {
return sex;
}
public void setSex(S sex) {
this.sex = sex;
}
@Override
public String toString() {
return "姓名:" + name + ",年龄:" + age + ",性别:" + sex;
}
}
// 使用
public class Generic {
public static void main(String[] args) {
Person<String, Integer, Character> person = new Person<String, Integer, Character>("蛋炒饭", 28, '男');
printPerson(person);
// 姓名:蛋炒饭,年龄:28,性别:男
}
// 泛型方法
private static <T> void printPerson(T person){
if ( person != null) {
System.out.println(person);
}
}
}