java基础-泛型原创
# 为什么要深入一下泛型?
本人最近开始在深读一些源码,发现有些底层的一下设计理解的不是很透彻,很多优秀的框架用到了各种各样的设计模式外加一些泛型去实现,不审核将泛型进行理解,感觉总是一头雾水。
# 定义
聊到泛型,我们第一个想到的就是,这个东西到底是干什么的,我想很大一部分小伙伴应该也是仅仅停留在偶尔使用这个水平上面,至于再深入一些,估计能说出来的够呛。书上这么说,泛型,即“参数化类型”。说到参数,我们知道,定义方法的时候是形参,传递实参。那何为参数化类型?对比着上面的理解,其实也很容易,说白了就是将原来的类型进行参数化。操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
# 特性
泛型只在编译阶段有效。我们看下如下代码:
/**
* @Author: maoba
* @Description:
* @Date: 2020-05-27 22:48
*/
public class GenericsDemo {
public static void main(String[] args) {
List<String> stringArrayList = new ArrayList<String>();
List<Integer> integerArrayList = new ArrayList<Integer>();
Class classStringArrayList = stringArrayList.getClass();
Class classIntegerArrayList = integerArrayList.getClass();
if(classStringArrayList.equals(classIntegerArrayList)){
System.out.println("泛型测试类型相同");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
最终我们输出的结果是“泛型测试类型相同”(大家可以直接拷贝本人的代码去运行一下)。这个结果说明了什么呢?说明在编译之后程序会采取去泛型化的措施。明明是不同的类型,但是class字节码却是同一份。也就是说明在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦除,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。简而言之,泛型信息不会进入到运行时阶段。
# 使用
开头的时候我们提到了,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。那么我们就分别来看一下这三种场景下泛型的使用。
# 泛型类
上述例子提到的List<String>,说白了就是一个泛型类。我们还是自己写一个,代码如下:
/**
* @Author: mao ba
* @Description: 泛型类例子
* @Date: 2020-05-27 22:58
* 说明:以下代码,其中"T"的类型都是由外部传入所定
*/
public class GenericsClassDemo<T> {
//内部定义一个T的属性
private T t;
//new出对象的时候传入该参数
GenericsClassDemo(T t){
this.t = t;
}
//再设置一个无参构造器
GenericsClassDemo(){
}
//同样地我们给T这个属性设置GET、SET方法、给 T传递值的时候有两种方式,
//1、通过构造器传递 2、通过set
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
调用函数:
public class GenericsTestMain {
public static void main(String[] args) {
/**说明,以下传入参数,并不是只是规定的String,Integer,Long等等,自定义的类型亦可**/
GenericsClassDemo<String> stringGenericsClassDemo = new GenericsClassDemo<String>("测试");
System.out.println(stringGenericsClassDemo.getT());
GenericsClassDemo<Integer> integerGenericsClassDemo = new GenericsClassDemo<Integer>();
integerGenericsClassDemo.setT(123);
System.out.println(integerGenericsClassDemo.getT());
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
输出结果,分别为:“测试”、“123”。
上次更新: 2022/11/30, 00:06:25