一、什么是泛型
泛型是一种程序设计手段。使用泛型机制写的程序代码要比随意使用Object变量,再进行强制类型转换具有更高的安全性和可读性。
即:
- 泛型如果没有限定类型,在编译时会使用Object类型;
- 类型安全监测机制,用<Integer>\或其他类型进行限定,编译器可以很方便的进行类型识别;
- 可读性强,一眼可以看出代码操作的数据类型
二、泛型的使用
1、定义一个泛型类
引入类型变量T,用<>括起来,放在类名后
public class Pair<T>{
}
2、定义一个泛型方法
class ArrayAlg{
public static <T> T getMiddle(T。。。 a){
return a[a.length / 2];
}
}
特点:
1、泛型方法可以定义在普通类中,也可以定义在泛型类中;
2、类型变量放在修饰符(上面是public static)之后,返回类型之前;
3、当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型
3、方法调用
String middle = ArrayAlg.<String>getMiddle("John","Q");
大多数情况下,<String>可以省略,即:
String middle = ArrayAlg.getMiddle("John","Q");
4、对定义泛型方法的说明
// <T>是为了定义一种范型,用来提前声明形参的类型是一个泛型变量。如果不提前声明,编辑器会报错,第二个T是正常的返回类型
相反的,在使用自定义的范型T之前,如果不首先使用<T>来声明范型变量的存在的话,编译器会有错误提示:
public <T> T test(T t){ return null; }
三、类型擦除
虚拟机没有泛型类型对象,所有对象都属于普通类。也就是说,在进入JVM之前,与泛型有关的信息都会被擦除,这个擦除就是类型擦除。
这些信息被擦除后,会用第一个限定的类型变量来替换。
public class ca<T> {
private Object first;
private T second;
public ca(Object first,T second){
this.first = first;
this.second = second;
}
public Object getFirst() {
return first;
}
public void setFirst(Object first) {
this.first = first;
}
public T getSecond() {
return second;
}
public void setSecond(T second) {
this.second = second;
}
}
在进入JVM之前,T会被擦除,换成Object,
如果把定义类那里的<T>改为<T extends String>\这样,T会被换成String类型,这就是类型擦除
泛型在集合中的体现
List<String> list1 = ArrayList<String>();
List<Integer> list2 = ArrayList<Integer>();
list1和list2的类型是相同的,在jvm中都是List.lass类型,至于<>中的String或者Integer则是一种标识,这种标识一方面提醒程序员,一方面检测操作的类型提高安全性。对于识别String和Integer则是通过反射来实现的。