一、介绍
泛型:参数化类型,使用广泛的类型。泛型是Java SE 1.5的新特性
使用场景:数据类型不确定
例如:现在要存储一个学生的成绩,但是成绩有可能想存为数字,小数,或者字符串(优秀,良好,好)之类的数据。这种数据都是类型不确定的。
可以使用Object来存储该成绩,但是这样存储的话会把所有类型都当做Object来对待。从而”丢失”了实际的数据类型。获取数据的时候也需要转换类型,效率低,还容易出错。
泛型的作用:
安全:在程序编译的时候就已经自动帮你检查类型了,比较安全。
省心:所有的类型转换都是自动和隐式的,提高代码的重用率。
泛型的定义格式:<字母>
字母可以是任意字母,但是大家都约定了常见字母的定义
字母 | 表示的类型 |
---|---|
T | Type表示类型 |
K V | 分别表示键值 |
E | 表示Element |
? | 表示不确定的类型 |
1、泛型类:不能使用在静态属性,静态方法上
class 类名<字母列表>{
修饰符 字母 属性;
修饰符 构造器(字母){
}
修饰符 返回类型 方法(字母){
}
}
例如:下面的Student类
public class Student<T1, T2> {
// 泛型不能使用在静态属性或者静态方法上:
// 因为静态属性和方法是从属于类,在编译的时候就确定了类型。所有不能用在静态属性和方法上
private T1 javaScope;// java成绩
private T2 oracleScope;// oracle成绩
public T1 getJavaScope() {
return javaScope;
}
public void setJavaScope(T1 javaScope) {
this.javaScope = javaScope;
}
public T2 getOracleScope() {
return oracleScope;
}
public void setOracleScope(T2 oracleScope) {
this.oracleScope = oracleScope;
}
public Student(T1 javaScope, T2 oracleScope) {
super();
this.javaScope = javaScope;
this.oracleScope = oracleScope;
}
public Student() {
}
}
等使用这个类的时候需要指定具体的类型
//这里的String和Integer只能是引用类型,不能是基本类型
Student<String,Integer> st = new Student<String,Integer>();
st.setJavaScope("优秀");//这里就自动变为只能是字符类型的参数了
Integer o = st.getOracleScope();//返回类型是Integer
int o1 = st.getOracleScope();//既然返回类型是Integer,同样可以自动拆箱。使用int接收
2、泛型接口:接口中泛型字母只能使用在方法中,不能使用在全局常量上
public interface Comperator<T> {
//T int A =2;//false:泛型不能使用在全局常量A上
void compare(T t);//true:使用在方法上
}
3、泛型方法:修饰符 < T > 返回类型 方法名(){}
泛型方法可以定义在普通类中,也可以定义在泛型类中
public class User {
//泛型方法:修饰符 <T> 返回类型 方法名(){}
public static <T> void test(T a){
System.out.println(a);
}
public static void main(String[] args) {
test("String");
}
}
4、泛型的范围:extends 表示<=
//关闭流 extends:表示<=Closeable 也就是只能是Closeable接口的实现类
public static <T extends Closeable> void closeIO(T...io){
for (T temp : io) {
if (temp!=null) {
try {
temp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二、总结
- 类型安全: 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。
- 消除强制类型转换: 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。避免了java.lang.ClassCastException异常
- 潜在的性能收益: 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。
- 安全简单:泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
- 泛型的类型参数只能是类类型(包括自定义类),不能是基本类型
- 在jdk1.7之后,构造函数中可以省略泛型类型。例如: