第一部分 认清楚 generics type
1. 为什么要用到泛型?
1)泛型历史和作用
历史:Java 泛型(generics)是 JDK 5 中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter)。声明的类型参数在编译期使用时用具体的类型来替换。
作用:让 Java 在编译的时候做强类型检查,以防止在运行期发声类型转换错误;
2)为什么要用泛型
我们看下面的例子:
List lt1 = new ArrayList();
lt1.add("hello");
lt1.add(22);
Integer a = (Integer) lt1.get(0); // 1. 由于没有泛型检查,这边当取值的时候需要强制转换,在运行期,还会报错,当类型不对。
`
运行期间的,不是预期的报错,这是我们线上程序所不期望看到的。
我们看下添加泛型的例子:
List list = new ArrayList<>();
list.add(222);
Integer b = list.get(0); //不需要强制转换,当取值的时候
list.add("hello"); //编译期间就直接报错了,而不是等到运行期才发现错误
`
发现编译后的 class 文件如下:
我们看一下上图,会发现泛型是编译期的,编译后的 class 会帮我们 list.get(0)的时候做一个强制的类型转换;
所以其实我们通过上图也可以发现泛型是编译期间的,运行期我们可以通过反射修改泛型变量里面的直的,利用反射这时候是不会做类型强制检查的;
2. 泛型的基本用法
1)应用在 class 上面
class 类名称 {
private 泛型标识 /*(成员变量类型)*/ var;
.....
}
}
`
此处 T 可以随便写为任意标识,常见的如 T、E、K、V 等形式的参数常用于表示泛型
在实例化泛型类时,必须指定 T 的具体类型
public class Generic{
//key 这个成员变量的类型为 T,T 的类型由外部指定
private T key;
public Generic(T key) { //泛型构造方法形参 key 的类型也为 T,T 的类型由外部指定
this.key = key;
}
public T getKey(){ //泛型方法 getKey 的返回值类型为 T,T 的类型由外部指定
return key;
}
}
其中大家一般普遍常用的泛型名字:
● E - Element (used extensively by the Java Collections Framework)
● K - Key
● N - Number
● T - Type
● V - Value
● S,U,V etc. - 2nd, 3rd, 4th types
2)应用在接口上面的例子:
public interface Pair {
public K getKey();
public V getValue();
}
public class OrderedPair implements Pair {
private K key;
private V value;
public OrderedPair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
我们可以这样使用: