------- android培训、java培训、期待与您交流! ----------
泛型
泛型基本应用:
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住程序中的非法输入,编译器编译带类型说明的集合时会除掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法返回值和原始类型完全一样。
了解泛型
ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语:
1.整个称为ArrayList<E>泛型类型
2.ArrayList<E>中的E称为类型变量或类型参数
3.整个ArrayList<Integer>称为参数化的类型
4.ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数
5.ArrayList<Integet>中的<>念着typeof
6.ArrayList称为原始类型
参数化类型与原始类型的兼容性:
1.参数化类型可以引用一个原始类型的对象,编译报告警告,例如,
2.Collection<String> c = new Vector();//可不可以,不就是编译器一句话的事吗?
3.原始类型可以引用一个参数化类型的对象,编译报告警告,例如,
4.Collection c = new Vector<String>();//原来的方法接受一个集合参数,新的类型也能传进去
参数化类型不考虑类型参数的继承关系:
1.Vector<String> v = new Vector<Object>();//错误!
2.Vector<Object> v = new Vector<String>();//也错误!
编译器也不允许创建类型变量的数组。在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面语句有错误:
Vector<Integer> vectorList[] = new Vector<Integer>[10];
泛型中的?通配符:
定义一个方法,该方法用于打印出任意参数化类型的集合中的所有数据,该方法如何定义?不能用于具体的参数操作,因为不确定传入的是什么参数,但是想size()方法可以,因为size()方法不涉及变量类型。
总结使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用于做引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
泛型中的?通配符的扩展
1.限定通配符的上边界:
正确:Vector<? extends Number> x = new Vector<Integer>();
错误:Vector<? extends Number> x = new Vector<String>();
2. 限定通配符的下边界:
正确:Vector<? super Integer> x = new Vector<Number>();
错误:Vector<? super Integer> x = new Vector<Byte>();
注:限定通配符总是包括自己。
定义泛型方法
1. 用于放置泛型的类型参数的尖括号应出现的其他所有修饰符之后和在方法的返回类型之前,也就是紧邻返回值之前。按照惯例,类型参数通常用单个大写字母表示。
2. 只有引用类型才能作为泛型方法的实际参数,基本类型不行...
3. 除了在应用泛型时可以使用extends限定符,在定义泛型时也可以使用extends限定符,例 如,Class.getAnnotation()方法的定义。并且可以用&来指导多个边界,如<V extends Serializable & cloneable> void method(){}
4. 普通方法、构造方法和静态方法中都可以使用泛型。
5. 也可以用类型变量表示异常,称为参数化的异常,可以用于方法的throws列表中,但是不能用于catch子句中。
6. 在泛型中可以同时有多个类型参数,在定义它们的尖括号中用逗号分,例如:public static <K,V> V getValue(K key){return map.get(key);}。
![](https://img-my.csdn.net/uploads/201212/05/1354700182_3827.png)
泛型类
如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型时,这时候就要采用泛型类型的方式进行定义,也就是类级别的泛型,定义的泛型在整个类中有效。如果被方法使用,那么如果泛型类的对象已经明确操作的具体类型后,所有要操作的类型就已经固定了。
类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量的,例如,如下两种方式都可以:
GenericDao<String> dao =null;
new GenericDao<String>();
在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。
当一个变量被声明为泛型时,只能被实例变量、方法和内部类调用,而不能被静态变量和静态方法调用。因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。
通过反射获得泛型的参数化类型
我们可以通过反射的方式得到使用泛型的方法之后,通过方法上getGenericParameterTypes()方法获取泛型的参数化类型。
![](https://img-my.csdn.net/uploads/201212/05/1354700292_9604.png)