泛型是Java 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是在获取的时候要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的,否则这将是一个安全隐患,引起classcastexcepiton。
实际上,Java中的泛型基本上都是在编译器这个层次来实现的,是伪泛型,编译之后就不会再体现泛型的相关信息了,因为所有的泛型信息都会在编译后被擦除掉,变成了原始类型,所以要理解泛型概念的首要前提就是要理解类型擦出(type erasure)。
如下的泛型类,
public class DataInfo<T> {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
编译之后会将类型擦除,变成类似下面的结构,JVM将只看DataInfo(原始类型),泛型参数类型已经不见了。
public class DataInfo {
private Object data;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
也就是说,我们在代码中定义的DataInfo s = new DataInfo(),以及DataInfo i = new DataInfo(),经过编译之后在内存中是同一个Class内存对象。
通过上面的说明,可以看出java的泛型实际上还是依托Object可以存储任意类型来实现的,只是泛型指定了参数类型,可以在编译阶段由编译器保证存放在Object中的类型都是泛型的指定的类型,不会导致classcastexception异常产生,即泛型只体现在编译期或之前,在运行期不会有泛型的概念。