黑马程序员-java高新技术学习之泛型 (二)

2014-11-24 11:33:11 · 作者: · 浏览: 15
oConvert(obj);


可以完成自动转换,因为范型T代表任意类型,因此他可以赋值给String类型的对象


2,定义一个方法,可以将任意类型的数组中的所有元素填充为相应类型的某个对象。


public static void fillArray(T[] a,T b) //将任意一个对象填充到任意类型的数组
{
for(int i =0;i {
a[i] =b ;
}
}


3,采用自定泛型方法的方式打印出任意参数化类型的集合中的所有内容。


public static void showCollection(Collection col,T obj) //利用范型来输出任意类型集合
{
col.add(obj) ;
for(T a:col)
{
System.out.println(a);
}
}


public static void showCollection(Collection< > col) //利用范型来输出任意类型集合
{
for(Object obj:col)
{
System.out.println(obj);
}
}


4,定义一个方法,把任意参数类型的集合中的数据安全地复制到相应类型的数组中。


public static void copy1(Collection dest,T[] src){

}


5,定义一个方法,把任意参数类型的一个数组中的数据安全地复制到相应类型的另一个数组中。


public static void copy2(T[] dest,T[] src){

}


如果一个类中多个方法都需要范型那么就是用类级别的范型。例如

class A
{
public void add(E obj){}
public E get(){}
private E data;
}


这样声明范型和在函数前面声明其实是一样的只不过是在类的级别上作用于整个类而已


要注意范型只是给编译器看的。


也就是说VectorVector他们用到的都是同一份字节码,字节码只有class文件加载到内存中的时候才有

所以在一个类中下面2个方法不能同时存在
void show(Vector) {}
void show(Vector){}

类型参数的类型推断


编译器判断范型方法的实际类型参数的过程称为类型推断,类型推断是相对于知觉推断的,其实现方法是一种非常复杂的过程。
根据调用泛型方法时实际传递的参数类型或返回值的类型来推断,具体规则如下:
当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处的实际应用类型来确定,这很容易凭着感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型,例如:
swap(new String[3],3,4) static void swap(E[] a, int i, int j)
当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型都对应同一种类型来确定,这很容易凭着感觉推断出来,例如:
add(3,5) static T add(T a, T b)
当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,且没有使用返回值,这时候取多个参数中的最大交集类型,例如,下面语句实际对应的类型就是Number了,编译没问题,只是运行时出问题:
fill(new Integer[3],3.5f) static void fill(T[] a, T v)
当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型, 并且使用返回值,这时候优先考虑返回值的类型,例如,下面语句实际对应的类型就是Integer了,编译将报告错误,将变量x的类型改为float,对比eclipse报告的错误提示,接着再将变量x类型改为Number,则没有了错误:
int x =(3,3.5f) static T add(T a, T b)
参数类型的类型推断具有传递性,下面第一种情况推断实际参数类型为Object,编译没有问题,而第二种情况则根据参数化的Vector类实例将类型变量直接确定为String类型,编译将出现问题:
copy(new Integer[5],new String[5]) static void copy(T[] a,T[] b);
copy(new Vector(), new Integer[5]) static void copy(Collection a , T[] b);


通过反射获得泛型的参数化类型


jdk1.5开始,一个方法可以通过反射获取到他的参数的参数化类型比如:put(Vector v),通过反射可以获取Date的类型


1.Method里面的方法:


Type[] getGenericParameterTypes()


按照声明顺序返回描述了此 Method 对象所表示的方法的形参类型的 Type 对象的数组。


Type getGenericReturnType()


返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象。


2.Type是接口,是ParameterizedType的父类


3.ParameterizedType 参数化类型 它放的是泛型的参数化类型实例


Type[] getActualTypeArguments()


返回表示参数的类的的类型参数的Type对象数组。


Type getOwnerType()


返回 Type 对象,返回此类的顶层类的类型。比如O.I,则返回 O 的表示形式


Type getRawType()


返回 Type 对象,表示声明此类型的类或接口。


代码示例


Method applyMethod = GenericTest.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]);


public static void applyVector(Vector v1){

}