图文详解 Java 泛型,写得太好了! (qq.com) 10道不得不会的Java基础面试题 (qq.com) 问题引入 我们在向集合中添加元素的过程中add()方法里填入的是Object类,而Object类是所有类的父类,这就
图文详解 Java 泛型,写得太好了! (qq.com)
10道不得不会的Java基础面试题 (qq.com)
问题引入
我们在向集合中添加元素的过程中add()方法里填入的是Object类,而Object类是所有类的父类,这就产生了一个问题——添加的类型无法统一,由此可能产生在遍历集合取出元素时类型不统一而报错。
传统的方式不能对添加到集合ArrayList中的数据类型进行约束。遍历的时候,需要进行类型转换,如果集合中的数据量较大,类型转换极大地影响程序效率。
Java 泛型(Generics) 是 JDK 5 中引入的一个新特性。
泛型提供了编译时类型安全检测机制,允许在编译时检测到非法的类型。使用泛型参数,可以增强代码的可读性以及稳定性。本质是参数化类型。
- 把类型当作是参数一样传递
- <数据类型>只能是引用类型,不能是基本数据类型如int
泛型:就是一种不确定的数据类型。
常用的通配符有T、E、K、V,?
?表示不确定的java类型
T type表示一个具体的java类型
K V分别代表java键值中的key、value
E element代表元素
使用泛型的好处
1 省略了强转的代码,提高效率;
2 可以把运行时的问题提前到编译时期,编译时就检查添加元素的类型,提高了安全性。
不用泛型时 用泛型时
追问:什么是泛型擦除?
泛型是提供给javac编译器使用的,用于限定集合的输入类型,让编译器在源代码级别上,避免向集合中插入非法数据。但编译器编译完带有泛型的java程序后,生成的class文件中不再带有泛型信息,以此使程序运行效率不受影响,这个过程称为擦除。
JVM并不知道泛型的存在,因为泛型在编译阶段就已被处理成普通的类和方法。处理机制是通过类型擦除,擦除规则:
- 泛型类型没有指定具体类型,使用Object作为原始类型;
- 若有限定类型< T exnteds XClass >,使用XClass作为原始类型;
- 若有多个限定< T exnteds XClass1 & XClass2 >,使用第一个边界类型XClass1作为原始类型;
追问:泛型的使用方式有哪几种?
泛型一般有三种使用方式:泛型类、泛型接口、泛型方法。
1.泛型类:
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{
private T key;
public Generic(T key) {
this.key = key;
}
public T getKey(){
return key;
}
}
2.泛型接口:
public interface Generator<T> {
public T method();
}
3.泛型方法:
public static < E > void printArray( E[] inputArray ){
for ( E element : inputArray ){
System.out.printf( "%s ", element );
}
System.out.println();
}
追问:项目中哪里用到了泛型?
- 自定义接口通用返回结果
CommonResult<T>
通过参数T
可根据具体的返回类型动态指定结果的数据类型 - 定义
Excel
处理类ExcelUtil<T>
用于动态指定Excel
导出的数据类型 - 构建集合工具类(参考
Collections
中的sort
,binarySearch
方法)