- 编写一个泛型方法,自动将Object类型的对象转换成其他类型。
//编写一个泛型方法,自动将Object类型的对象转换成其他类型。
private static <T> T autoConvert(Object obj){ return (T)obj; }
- 定义一个方法,可以将任意类型的数组中的所有元素填充为相应类型的某个对象。
//定义一个方法,可以将任意类型的数组中的所有元素填充内容为相应类型的某个对象 private static <T> void fillArray(T[] a,T obj){ for(int i=0;i<a.length;i++){ a[i]=obj; } }
- 采用自定义泛型方法的方式打印出任意参数化类型的集合中的所有内容。
- 在这种情况下,前面的通配符方案要比泛型方法更有效,当一个类型变量用来表达两个参数之间或者参数和返回值之间的关系时,即同一个类型变量在方法签名的两处被使用,或者类型变量在方法体代码中也被使用而不是在签名的时候使用,才需要使用泛型方法。
private static void printObject1(Collection<?> collection){ System.out.println(collection.size()); for(Object o:collection){ System.out.println(o); } }
//采用自定义泛型方法的方式打印出任意参数化类型的集合中的所有内容。 private static <T> void printObject2(Collection<T> collection,T obj){ for(Object o:collection){ System.out.println(o); } collection.add(obj);//T的方式可以向集合中进行添加 }
- 定义一个方法,把任意参数类型的集合中的数据安全地复制到相应的数组中。
//定义一个方法,把任意参数类型的集合中的数据安全地复制到相应的数组中 private static <T> void copy1(Collection<T> dest,T[] src){ for(int i=0;i<src.length;i++){ dest.add(src[i]); } } copy1(new Vector<String>(),new String[]{}); copy1(new Vector<Date>(),new String[]{});//出错!传播:Vector进行参数化时,指定了T就是Date,那么后面的另一个参数T 就必须是Date[]
- 定义一个方法,把任意参数类型的一个数组中的数据安全地复制到相应类型的另一个数组中。
//定义一个方法,把任意参数类型的一个数组中的数据安全地复制到相应类型的另一个数组中。
private static <T> void copy2(T[] dest,T[] src){ }
- 编译器判断泛型方法的实际类型参数的过程称为类型推断,类型推断是相对于知觉推断的,其实现方法是一种非常复杂的过程。
- 根据调用泛型方法时实际传递的参数类型或者返回值类型来推断,具体规则如下:
- 当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处的实际应用类型来确定,这很容易凭着感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型,例如:
swap(new String[3],3,4)—>static <E> void swap(E[] a,int i,int j)
- 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型来确定,这很容易凭着感觉推断出来,例如:
add()—>static <T>T add(T a,T b)
- 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,且没有使用返回值,这时候取多个参数中的最大交集类型,例如,下面的语句实际对应的类型就是Number了,编译没问题,只是运行时出问题:
fill(new Integer[3],3.5f)—>static <T> void fill(T[] a,T v)
- 当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际引用类型对应到了不同的类型,并且使用返回值,这时候优先考虑返回值的类型,例如下面的语句实际对应的类型就是Integer了,编译器将报告错误,将变量x的类型改为float,对比eclipse报告的错误提示,接着再将x类型改为Number,则没有了错误:
int x=add(3,3.5f)—>static <T> T add(T a,T b)
- 参数类型的类型推断具有传递性,下面第一种情况推断实际参数为Object,编译没有问题,而第二种情况则根据参数化的Vector类实例将类型变量直接确定为String类型,编译将出现问题:
copy(new Integer[5],new String[5])—>static <T> void copy(T[] a,T[] b);