Java学习-泛型
体验泛型
在Jdk1.5之后,定义集合时需要你明确集合中要装哪种类型的数据,无法加入指定类型之外的数据。1
2
3
4ArrayList<Integer> arr1 = new ArrayList<Integer>();
arr1.add(1);
arr1.add("aa"); //有的泛型之后,此行代码在编译的时候会报错
int x = arr1.get(0); //有了泛型之后,取数据的时候不需要进行强制类型转换
什么是泛型
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序的非法输入。
需要注意的是:编译器编译带类型参数的集合时会出掉“类型”信息,使程序运行的效率不受影响。对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译器生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往泛型集合中加入其它类型的数据。
举例,用泛型得到集合,再调用其add方法1
2
3ArrayList<Integer> arr1 = new ArrayList<Integer>();
arr1.getClass().getMethod("add", Object.class).invoke(arr1, "aaa");
System.out.println(arr1.get(0)); //可以在控制台输出aaa
了解泛型
ArrayList
整个类型被称为ArrayList
ArrayList
ArrayList
Integer为实际类型参数
参数化类型可以引用一个原始类型的对象:1
Collection<String> c = new Vector();
原始类型可以引用一个参数化类型的对象:1
Collection c = new Vector<String>();
参数化类型不考虑类型参数之间的继承关系:1
2Vector<Object> v = new Vector<String>();
Vector<String> v = new Vector<Object>();
以上的定义是错误的!
泛型的通配符
Collection<?>可以匹配任何参数类型,但具体匹配的是什么类型只有以后才知道。通配符定义的变量主要做引用,可以调用与参数无关的方法,不能调用与参数有关的方法。
举例:1
2
3
4
5
6
7
8public static void printCollection(Collection<?> cols){
for(Object obj:cols){
System.out.println(obj);
}
cols.add("aaa"); //错误!!因为通配符不能确定之后匹配的一定就是String类型
int len = cols.size(); //可以!!可以调用与参数无关的方法
}
泛型集合的应用案例
1 | Map<String, Integer> maps = new HashMap<String, Integer>(); |
自定义泛型方法
例1
1 | public <T> void swap(T[],int i,int j){ |
例2:将Object转成自定义返回类型
1 | public <T> T autoConvert(Object obj){ |
自定义泛型类的应用
如果一个类的实例对象中多处都要用到同一个泛型参数,即这些地方引用的泛型类型保持同一个实际类型时,这时候就要采用泛型类型的方法进行定义,也就是类姐的泛型,语法格式如下:1
2
3
4
5
6
7
8
9public class GenericDao<T>{
private T field ;
public void save(T obj){
}
public T getById(int id){
}
}
使用如下代码进行方法调用:1
2GenericDao<Person> dao = new GenericDao<Person>();
dao.save(...);