泛型方法的使用

一 泛型方法的介绍

如果定义类、接口是没有使用类型形参,但定义方法时想自己定义类型形参,这也是可以的,JDK1.5还提供了泛型方法的支持。

泛型方法的语法格式为:

修饰符 <T , S> 返回值类型 方法名(形参列表)

{

     //方法体...

}

泛型方法的方法签名比普通方法的方法签名多了类型形参声明,类型形参声明以尖括号括起来,多个类型形参之间以逗号(,)隔开,所有类型形参声明放在方法修饰符和方法返回值类型之间。

二 泛型方法的正确使用

1 代码示例

扫描二维码关注公众号,回复: 579294 查看本文章
import java.util.*;

public class GenericMethodTest
{
	// 声明一个泛型方法,该泛型方法中带一个T类型形参,
	static <T> void fromArrayToCollection(T[] a, Collection<T> c)
	{
		for (T o : a)
		{
			c.add(o);
		}
	}
	public static void main(String[] args)
	{
		Object[] oa = new Object[100];
		Collection<Object> co = new ArrayList<>();
		// 下面代码中T代表Object类型
		fromArrayToCollection(oa, co);
		String[] sa = new String[100];
		Collection<String> cs = new ArrayList<>();
		// 下面代码中T代表String类型
		fromArrayToCollection(sa, cs);
		// 下面代码中T代表Object类型
		fromArrayToCollection(sa, co);
		Integer[] ia = new Integer[100];
		Float[] fa = new Float[100];
		Number[] na = new Number[100];
		Collection<Number> cn = new ArrayList<>();
		// 下面代码中T代表Number类型
		fromArrayToCollection(ia, cn);
		// 下面代码中T代表Number类型
		fromArrayToCollection(fa, cn);
		// 下面代码中T代表Number类型
		fromArrayToCollection(na, cn);
		// 下面代码中T代表Object类型
		fromArrayToCollection(na, co);
		// 下面代码中T代表String类型,但na是一个Number数组,
		// 因为Number既不是String类型,
		// 也不是它的子类,所以出现编译错误
//		fromArrayToCollection(na, cs);
	}
}

2 代码说明

与类、接口中使用泛型参数不同的是,方法中的泛型参数无需显式传入实际类型参数,因为编译器根据实参推断类型形参的值。它通常推断出最直接的类型参数。例如:调用如下代码。

fromArrayToCollection(sa, cs);
上面代码中cs是一个Collection<String>类型,与方法定义时的fromArrayToCollection(T[] a, Collection<T> c)进行比较,只比较泛型参数,不能发现该T类型形参代表的实际类型是String类型。

三 泛型方法的错误使用

1 代码示例

import java.util.*;

public class ErrorTest
{
	// 声明一个泛型方法,该泛型方法中带一个T类型形参
	static <T> void test(Collection<T> from, Collection<T> to)
	{
		for (T ele : from)
		{
			to.add(ele);
		}
	}
	public static void main(String[] args)
	{
		List<Object> as = new ArrayList<>();
		List<String> ao = new ArrayList<>();
		// 下面代码将产生编译错误
		test(as , ao);
	}
} 

2 运行结果

 E:\test\Java\Java8\fanxing\src>javac ErrorTest.java
ErrorTest.java:20: 错误: 无法将类 ErrorTest中的方法 test应用到给定类型;
                test(as , ao);
                ^
  需要: Collection<T>,Collection<T>
  找到: List<Object>,List<String>
  原因: 推断类型不符合等式约束条件
    推断: String
    等式约束条件: String,Object
  其中, T是类型变量:
    T扩展已在方法 <T>test(Collection<T>,Collection<T>)中声明的Object
1 个错误

3 代码说明

上面程序中调用了test方法传入了两个实际参数,其中as的数据类型是List<String>,而ao的数据类型是List<Object>,与泛型方法签名进行对比test(Collection<T> a,Collection<T> c),编译器无法正确识别T所代表实际类型。

四 改进上面这个例子

1 代码示例

import java.util.*;

public class RightTest
{
	// 声明一个泛型方法,该泛型方法中带一个T形参
	static <T> void test(Collection<? extends T> from , Collection<T> to)
	{
		for (T ele : from)
		{
			to.add(ele);
		}
	}
	public static void main(String[] args)
	{
		List<Object> ao = new ArrayList<>();
		List<String> as = new ArrayList<>();
		// 下面代码完全正常
		test(as , ao);
	}
}

2 代码说明

该代码可以编译通过,它改变了test签名,将该方法的前一个形参类型改为Collection<? extends T>,这种采用类型通配符的表示方式,只要test方法的前一个Collection集合里的元素类型是后一个Collection集合里的元素类型的子类即可。

猜你喜欢

转载自cakin24.iteye.com/blog/2324686