泛型,就是”参数化类型“,在创建对象或调用方法时才指定类型。好处就是代码更加简洁(不需要强壮),程序更加健壮(在编译期间不会告警,在运行期间不会出现ClaaCastException异常)。
日常开发中,接口、类和方法都可以使用泛型去定义,但没有所谓的泛型数组一说。因为泛型具有擦除机制,运行时的类型参数会被擦除,Java只知道这是一个Object对象,而数组必须知道所持有对象的具体类型,这种安全检查原则与泛型擦除机制是相悖的。
在泛型类,泛型接口,泛型方法的定义过程中,常用T,E,K,V等形式的参数表示形参,由接收外部调用的时候传入实参。对于传入的多种类型,相应对象的实例类型都是一样的。
package com.teligen.backendproject.test; public class Box{ private T data; public Box(){ } public Box(T data) { this.data = data; } public T getData() { return data; } }
package com.teligen.backendproject.test;
public class GenericTest {
public static void main(String[] args) {
Box name = new Box<>("liu");
Box age = new Box<>(18);
// class com.teligen.backendproject.test.Box
System.out.println("name class :" + name.getClass());
// class com.teligen.backendproject.test.Box
System.out.println("age class : " + age.getClass());
// true
System.out.println(name.getClass() == age.getClass());
}
}
类型通配符
在这个Box
public T getData(Box> box) {
return data;
}
package com.teligen.backendproject.test;
public class GenericTest {
public static void main(String[] args) {
Box name = new Box<>("liu");
Box age = new Box<>(18);
Box num = new Box<>(1001);
System.out.println(age.getData(age)); // liu
System.out.println(name.getData(name)); // 18
System.out.println(num.getData(num)); // 1001
}
}
此外,我们还有可能听到通配符上限和通配符下限。实际就是对类型通配符?做进一步的限制,只能是传入实参的父类或者子类。
// 通配符上限,接收父类
public T getData(Box super Number> box) {
return data;
}
// 通配符下限,接收子类
public T getData(Box extends Number> box) {
return data;
}
注意事项:
1、不能使用基本数据类型实例化类型参数
2、不能实例化泛型类型的数组
3、不能实例化类型参数
4、运行时检查不适用于泛型



