------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
(1)泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合后会去掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的泛型信息,只要能跳过编译器,就可以往谋个泛型集合中加入其他类型的数据,例如,用反射得到集合,再调用其add方法即可。
ArrayList<Integer> collection=new ArrayList<Integer>();
collection.getClass().getMethod("add",Object.class).invoke(collection,"abc");
System.out.println(collection.get(0));
运行结果:abc
(2)ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语:
整个称为ArrayList<E>泛型类型
ArrayList<E>中的E称为类型变量或类型参数
整个ArrayList<Integer>称为参数化的类型
ArrayList<Integer>中的Integer称为类型参数的实例或者实际类型参数
ArrayList<Integer>中的<>念typeof
ArrayList称为原始类型
(3)参数化类型与原始类型的兼容性:
参数化类型可以引用一个原始类型的对象,编译报告警告,例如:
Collection<String> c=new Vector();//可以编译通过
原始类型可以引用一个参数化类型的对象,编译报告警告,例如:
Collection c=new Vector<String>();//可以
(4)参数化类型不考虑类型参数的继承关系
Vector <String> v=new Vector<Object>();//错误
Vector<Object> v=new Vector<String>();//错误
(5)在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面的语句有错误:
Vector<Integer> vectorList[]=new Vector<Integer>[10];
(6)泛型的应用
HashMap<String, Integer> maps=new HashMap<String,Integer>();
maps.put("zxx", 28);
maps.put("lhm", 35);
maps.put("flx", 33);
//获取Entry的Set集合
Set<Map.Entry<String, Integer>> entrySet=maps.entrySet();
for (Map.Entry<String, Integer> entry :entrySet) {
System.out.println(entry.getKey() +":" +entry.getValue());;
}
(7)自定义泛型方法
A,交换数组中的两个元素的位置的泛型方法语法定义:
private static <T> void swap(T[] a,int i,int j){
T tmp=a[i];
a[i]=a[j];
a[j]=tmp;
}
B,用于放置泛型的类型参数的尖括号应出现在方法的其他所有修饰符之后和在方法的返回值之前,也就是紧邻返回值之前。按照惯例,类型参数通常用单个大写字母表示
C,只有引用类型才能作为泛型方法的实际参数,swap(new int[]{1,2,3},1,2);
语句会报告编译错误。
(8)定义泛型类
A,如果类的实例对象中多处都要用到同一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型时,这时候要采用泛型类型的方式进行定义,也就是类级别的泛型,语法格式:
public classGenericDao<E> {
public void add(E t){
}
public EfindById(int id){
return null;
}
}
B,类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量,例如,如下两种方式都可以:
GenericDao<String> dao=null;
new GenericDao<String>();
C,在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型
当一个变量被声明为泛型时,只能被实例变量和方法调用(还有内嵌类型)
而不能被静态变量和静态方法调用。因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。