《Java开发技术大全》第10章泛型,本章将介绍泛型的语法和应用,同时展示泛型如何提供类型安全。本节为大家介绍泛型方法。
AD:
10.6 泛型方法
在C++中,除了可以创建模板类,还可以创建模板函数。在Java中也提供了类似的功能:泛型方法。一个方法如果被声明成泛型方法,那么它将拥有一个或多个类型参数,不过与泛型类不同,这些类型参数只能在它所修饰的泛型方法中使用。
创建一个泛型方法常用的形式如下:
[访问权限修饰符] [static] [final] <类型参数列表> 返回值类型 方法名([形式参数列表]) |
访问权限修饰符(包括private、public、protected)、static和final都必须写在类型参数列表的前面。
返回值类型必须写在类型参数表的后面。
泛型方法可以写在一个泛型类中,也可以写在一个普通类中。由于在泛型类中的任何方法,本质上都是泛型方法,所以在实际使用中,很少会在泛型类中再用上面的形式来定义泛型方法。
类型参数可以用在方法体中修饰局部变量,也可以用在方法的参数表中,修饰形式参数。
泛型方法可以是实例方法或是静态方法。类型参数可以使用在静态方法中,这是与泛型类的重要区别。
使用一个泛型方法通常有两种形式:
<对象名|类名>.<实际类型>方法名(实际参数表); |
和:
[对象名|类名].方法名(实际参数表); |
如果泛型方法是实例方法,要使用对象名作为前缀。如果是静态方法,则可以使用对象名或类名作为前缀。如果是在类的内部调用,且采用第二种形式,则前缀都可以省略。
注意到这两种调用方法的差别在于前面是否显示地指定了实际类型。是否要使用实际类型,需要根据泛型方法的声明形式以及调用时的实际情况(就是看编译器能否从实际参数表中获得足够的类型信息)来决定。下面来看一个例子。
【例10.5】 泛型方法使用示例。
//--------------文件名demoGenMethods.java,程序编号10.10----------- public class demoGenMethods{ //定义泛型方法,有一个形式参数用类型参数T来定义 public static <T> void showGenMsg(T ob, int n){ T localOb = ob; //局部变量也可以用类型参数T来定义 System.out.println(localOb.getClass().getName()); } public static <T> void showGenMsg(T ob){ System.out.println(ob.getClass().getName()); } public static void main(String args[]){ String str = "parameter"; Integer k = new Integer(123); //用两种不同的方法调用泛型方法 demoGenMethods.<Integer>showGenMsg(k,1); showGenMsg(str); } } |
程序中定义的两个泛型方法都是静态方法,这在泛型类中是不允许的。而且这两个泛型方法相互重载(参数的个数不同)。在方法体中,类型参数T的使用和泛型类中的使用是相同的。
再来看看如何调用这两个泛型方法:
demoGenMethods.<Integer>showGenMsg(k,1); showGenMsg(str); |
<Integer>showGenMsg(k,1); |
由于传递了一个实际的类型参数Integer,所以编译器知道如何将方法内部的占位符T替换掉。不过需要注意,实际参数k的类型必须也是Integer型,否则编译器会报错。
第二种调用形式明显要简洁一些:
showGenMsg(str); |
java.lang.Integer java.lang.String |
public <T> void doSomething(){ T ob; …… } |
调用它的时候,根本就没有实际参数,所以编译器无法知道T的实际类型,这种情况下,就必须使用第一种形式。
前面还提到,泛型方法也可以写在泛型类中,比如:
public class Generic<T>{ public <U> void showGenMsg(U ob){ System.out.println(ob.getClass().getName()); } …… } |
public class Generic<T, U>{ public void showGenMsg(U ob){ System.out.println(ob.getClass().getName()); } …… } |
public class TestExternal {
public static <T> T get(String str){
return (T)str;
}
public static void main(String[] args) {
int str=TestExternal.get("");
}
}