背景
在使用泛型之前,要想将程序类,集合等设置成共通类型,那么只能通过设置为Object类型,然后在用到真实类型的时候进行强制转换,这样设计出来的代码往往阅读性与安全性都不高。程序中借助泛型可以完美的结局这些问题。
泛型的基础应用
- 定义
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
泛型的简单应用
- 定义简单泛型类
public class Page<T> {
private Integer pageSize;
private Integer pageNo;
private List<T> list;
}
2.方法泛型,返回中间位置元素
public static <T> T getMiddle(T... t){
//业务处理
return t[t.length/2];
}
3.类型变量约定 可以约定类的实现
public static <T extends Comparable> T min(T... a){
T smallest = a[0];
for (int i = 1; i < a.length; i++)
if (smallest.compareTo(a[i])>0)smallest = a[i];
return smallest;
}
开发中泛型示例
- mybatis-plus中应用
2.jpa的使用
3.集合类中的使用
泛型符号代表的含义
E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
?- 表示不确定的java类型
类型擦除
类型檫除定义
类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法
类型檫除过程:
1.将所有的泛型参数用其最顶级的父类型替换。像Page ,可以用Object替换,然后调用的时候再插入强制转换为指定类型
//檫除前
public class Page<T> {
}
檫除后
public class Page {
}
2.移除所有的类型参数。
//檫除前
public static <T extends Comparable> T min(T[] a){
}
//檫除后
public static Comparable T min(T[] a){
}
类型檫除带来的问题
1.用同一泛型类的实例区分方参数是不行的
//代码会报错
class Erasure{
private void test(List<String> ls){
System.out.println("Sting");
}
private void test(List<Integer> li){
System.out.println("Integer");
}
}
泛型类的静态变量是共享的
public class StaticTest{
public static void main(String[] args){
GT<Integer> gti = new GT<Integer>();
gti.var=1;
GT<String> gts = new GT<String>();
gts.var=2;
System.out.println(gti.var);
}
}
class GT<T>{
public static int var=0;
public void nothing(T x){}
}
泛型檫除总结
- 虚拟机中没有泛型,只有普通类和普通方法
- 所有泛型类的类型参数在编译时都会被擦除
泛型总结
- 类型安全。 泛型可以使编译器知道一个对象的限定类型是什么,这样编译器就可以在一个高的程度上验证这个类型。
- 消除强制类型转换。
- 提高代码的重用率