你真的了解Java泛型吗?
《你真的了解Java泛型吗?》共 0.6 万字,通篇围绕 场景、安全、需求 展开,归在「后端与系统架构」这一层。
适合给 AI 系统搭底座、要管得住的人
目录骨架(8 节)
- 一、泛型概述
- 泛型高级篇
- 什么是泛型?为什么要使用泛型?
- 2. 泛型使用场景
- 3.总结
- 三、泛型方法
- 四、泛型接口
- 五、类型擦除
一、泛型概述
什么是泛型?为什么要使用泛型?
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参列表,普通方法的形参列表中,每个形参的数据类型是确定的,而变量是一个参数。在调用普通方法时需要传入对应形参数据类型的变量(实参),若传入的实参与形参定义的数据类型不匹配,则会报错
那参数化类型是什么?以方法的定义为例,在方法定义时,将方法签名中的形参的数据类型也设置为参数(也可称之为类型参数),在调用该方法时再从外部传入一个具体的数据类型和变量。
泛型的本质是为了将类型参数化, 也就是说在泛型使用过程中,数据类型被设置为一个参数,在使用时再从外部传入一个数据类型;而一旦传入了具体的数据类型后,传入变量(实参)的数据类型如果不匹配,编译器就会直接报错。这种参数化类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
2. 泛型使用场景
在 ArrayList 集合中,可以放入所有类型的对象,假设现在需要一个只存储了 String 类型对象的 ArrayList 集合。
/**
* @Auth:TianMing
* @Description: 基本应用
*/
public class demo1 {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
for(String s:list){
System.out.println(s);
}
}
}
//上面代码没有任何问题,在遍历 ArrayList 集合时,只需将 Object 对象进行向下转型成 String 类型即可得到 String 类型对象。
// 但如果在添加 String 对象时,不小心添加了一个 Integer 对象,会发生什么?看下面代码:
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add(666);
for (int i = 0; i < list.size(); i++) {
System.out.println((String)list.get(i));
}
}

上述代码在编译时没有报错,但在运行时却抛出了一个 ClassCastException 异常,其原因是 Integer 对象不能强转为 String 类型。
那如何可以避免上述异常的出现?即我们希望当我们向集合中添加了不符合类型要求的对象时,编译器能直接给我们报错,而不是在程序运行后才产生异常。这个时候便可以使用泛型了。
使用泛型代码如下:
/**
* @Auth:TianMing
* @Description: 基本应用
*/
public static void main(String[] args) {
ArrayList<String> list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//list.add(666);// 在编译阶段,编译器会报错
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
< String > 是一个泛型,其限制了 ArrayList 集合中存放对象的数据类型只能是 String,当添加一个非 String 对象时,编译器会直接报错。这样,我们便解决了上面产生的 ClassCastException 异常的问题(这样体现了泛型的类型安全检测机制)。
3.总结
泛型的好处
简单总结出泛型的几点好处
(1)统一数据类型,对于后续业务层中取出数据有很强的统一规范性,方便对数据的管理;
(2)把运行时期的问题提前到了编译期,避免了强转类型转换可能出现的异常,降低了程序出错的概率;
泛型的出现就是为了统一集合当中数据类型的

泛型高级篇
二、泛型类 泛型的使用方法非常多,这里来简单说一下泛型类的使用;泛型类,就是把泛型定义在类上。
泛型类的使用场景:当一个类中,某个变量的数据不确定时,就可以定义带有泛型的类。
我们平常所用的ArrayList类,就是一个泛型类,我们看如下源码

ArrayList 源码上显示,在ArrayList类的后面,便是 <E>泛型,定义了这样的泛型,就可以让使用者在创建ArrayList对象时自主定义要存放的数据类型。
