泛型是 Java 中的一个特性,它允许我们在定义接口、类、方法时使用类型参数,以实现代码的重用和类型安全。
需要注意的是,泛型在编译时期进行类型擦除,运行时并不保留泛型的具体类型信息。因此,在运行时无法获取泛型的具体类型参数。
使用泛型的主要好处包括:
1、类型安全:通过泛型可以在编译时期对代码进行类型检查,避免了在运行时期出现类型转换异常。
2、代码重用:通过定义泛型类或泛型方法,可以在不同的数据类型之间进行通用操作,提高代码的复用性。
3、程序可读性和可维护性:通过使用泛型,可以明确代码的含义和目的,使代码更易读懂和维护。
接口泛型
定义一个接口泛型:
public interface IMyInterface<T> {
/**
* 定义含有泛型的接口
*
* @param msg
* @return
*/
T getMsg(T msg);
}
使用接口泛型(在实现接口的类中,可以指定具体的类型参数来确定接口的泛型类型):
/**
* 确定了泛型类型为String
*/
public class MyInterfaceImpl implements IMyInterface<String> {
@Override
public String getMsg(String msg) {
return msg;
}
}
/**
* 确定了泛型类型为Employee
*/
public class MyInterfaceImpl2 implements IMyInterface<Employee> {
@Override
public Employee getMsg(Employee msg) {
return msg;
}
}
类泛型
定义一个类泛型
public class Result<M, T> {
private M x;
private T data;
public M getX() {
return x;
}
public void setX(M x) {
this.x = x;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
使用类泛型(在创建类的实例时指定具体的类型参数)
public static void main(String[] args) {
// 创建Result的实例,确定了泛型M对应String,泛型T对应 List<String>
Result<String, List<String>> result = new Result<>();
result.setX("我是字符串");
result.setData(Arrays.asList("1", "2"));
}
方法泛型
public class TestDemo2 {
/**
* 定义在方法上的泛型,要在调用时确定
*
* @param m
* @param <M>
* @return
*/
public static <M> M getMsg(M m) {
return m;
}
// 定义在方法上的泛型,调用时候确定,多个泛型参数
public static <M, N> M getMsg(M m, N n) {
return m;
}
/**
* ?通配符,不确定类型,代码集合可以接收任意类型数据
*
* @param list
*/
public static List<?> test1(List<?> list) {
List<?> collect = list.stream().filter(Objects::nonNull).collect(Collectors.toList());
return collect;
}
/**
* ? extends E 限定了上限,集合的泛型,E以及E的子类
*
* @param list
* @return
*/
public static List<?> test2(List<? extends Employee> list) {
List<?> collect = list.stream().filter(Objects::nonNull).collect(Collectors.toList());
return collect;
}
/**
* ? super E 限定了下限,集合的泛型,E及E的父类
*
* @param list
* @return
*/
public static List<?> test3(List<? super Seller> list) {
List<?> collect = list.stream().filter(Objects::nonNull).collect(Collectors.toList());
return collect;
}
public static void main(String[] args) {
// 定义在方法上的泛型,要在调用时确定
getMsg("我是字符串");
getMsg(100);
getMsg(100L);
getMsg("我是字符串", 100);
getMsg("我是字符串", true);
// ?通配符,不确定类型,代码集合可以接收任意类型数据
List<String> list1 = new ArrayList<>();
List<Employee> list2 = new ArrayList<>();
test1(list1);
test1(list2);
// Seller extends Employee
// ? extends E 限定了上限,集合的泛型,E以及E的子类
List<Employee> list3 = new ArrayList<>();
List<Seller> list4 = new ArrayList<>();
List<Student> studentList = new ArrayList<>();
test2(list3);
test2(list4);
//test2(studentList);//错误
// ? super E 限定了下限,集合的泛型,E及E的父类
List<Employee> employeeList = new ArrayList<>();
List<Seller> sellerList1 = new ArrayList<>();
List<Student> studentList1 = new ArrayList<>();
test3(employeeList);
test3(sellerList1);
//test3(studentList1);// 错误
}
}