第一部分 认清楚 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 文件如下:

Java 反射推断泛型 java反射和泛型_Java 反射推断泛型

我们看一下上图,会发现泛型是编译期的,编译后的 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; }
}

我们可以这样使用: