------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
泛型的基本应用:
》泛型经常在集合中运用,当使用泛型,那么就不需要强制类型转换了,并未把错误提前到编译器,方便程序员解决问题。
》泛型是提供给Jvac编译器使用的,可以限定集合中输入类型,编译器编译带类型说明的集合时会去掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其他类型的数据,例如:反射得到集合,再调用add方法。
泛型是给编译器看的,运行没有泛型。
Vector<String> v=new Vector<Obejct>();//错误
Vector<Obejct> v=new Vector<String>();//错误
参数化类型不考虑继承关系。
参数化类型和原始类型的兼容性:
参数化类型可以引用一个原始类型
Collection<String> c=new Vector();
原始数据类型也可以引用参数化类型
Collection c=new Vector<String>();
注意:(1)可以用类型变量表示异常,称为参数化异常,可以用于方法的Throws列表中,但不能用catch子句中。
(2)数组中的元素不能使用参数化的类型。
泛型练习:
①定义方法,自动将Object类型转换其他类型
public <T> T trans(Object obj){
return (T)obj;
}
②任意类型数组填充为对象
public <T> void arr(T[] array,T obj){
for(int i=0;i<array.length;i++){
array[i]=obj;
}
}
③采用自定义泛型方式打印出任意类型的集合
public <T> void gene(Collection<T> collection,T obj){
for(Object obj2:collection){
System.out.println(obj2);
}
System.out.println(obj);
}
④把任意集合数据复制到相应类型数组中
public <T> void copy(Collection<T> coll,T[] arr){
Iterator<T> it=coll.iterator();
for(int i=0;i<arr.length;){
while(it.hasNext()){
arr[i]=it.next();
i++;
}
}
}
类型参数的类型判断:
编译器判断泛型方法的实际类型参数的过程称为类型推断。
1>当某个类型变量只有在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处的实际参数类型来确定。swap(newString[],3,4)------->static <E> void swap(E[] a,int b,int c);
2>当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型都对应同一种类型来确定。add(2,3)------>static <T> add(T a,T b);
3>当某个类型变量在整个参数列表中所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型都对应不同的类型,且没使用返回值,这是读取参数中最大交集类型。
fill(new Integer[],3.5f)------->static <T> void fill(T[] t,T V);
4>当某个类型变量在整个参数列表中所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型都对应不同的类型,并且使用返回值,这是优先考虑返回值类型。int x=(3,3.5f)------>static <T> T add(T a,T b);
通过反射获得泛型的事件类型参数:
package genericity;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Vector;
public class GenetricTest {
//定义一个带有泛型参数的方法
public static void applyVector(Vector<Date> v1){
}
//通过反射得到参数泛型类型
public static void main(String[] args)throws Exception{
//通过反射获得方法
Method applyMethod=GenetricTest.class.getMethod("applyVector", Vector.class);
//获得形参类型
Type[] types=applyMethod.getGenericParameterTypes();
//把形参强转为参数化类型
ParameterizedType ptype=(ParameterizedType)types[0];
//得到声明此类型的类
System.out.println(ptype.getRawType());
//得到此类型的实际参数类型
System.out.println(ptype.getActualTypeArguments()[0]);
}
}
运行结果:
以泛型方式得到参数类型。
原始类型
参数类型-------很多框架都是这么实现的。获得实际参数类型。