在Java中也提供了类似的功能:泛型方法。一个方法如果被声明成泛型方法,那么它将拥有一个或多个类型参数,不过与泛型类不同,这些类型参数只能在它所修饰的泛型方法中使用。 创建一个泛型方法常用的形式如下: [访问权限修饰符] [static] [final] <类型参数列表> 返回值类型 方法名([形式参数列表]) 访问权限修饰符(包括private、public、protected)、static和final都必须写在类型参数列表的前面。 返回值类型必须写在类型参数表的后面。 泛型方法可以写在一个泛型类中,也可以写在一个普通类中。由于在泛型类中的任何方法,本质上都是泛型方法,所以在实际使用中,很少会在泛型类中再用上面的形式来定义泛型方法。 类型参数可以用在方法体中修饰局部变量,也可以用在方法的参数表中,修饰形式参数。 泛型方法可以是实例方法或是静态方法。类型参数可以使用在静态方法中,这是与泛型类的重要区别。使用一个泛型方法通常有两种形式: <对象名|类名>.<实际类型>方法名(实际参数表); [对象名|类名].方法名(实际参数表); 如果泛型方法是实例方法,要使用对象名作为前缀。如果是静态方法,则可以使用对象名或类名作为前缀。如果是在类的内部调用,且采用第二种形式,则前缀都可以省略。 注意到这两种调用方法的差别在于前面是否显示地指定了实际类型。是否要使用实际类型,需要根据泛型方法的声明形式以及调用时的实际情况(就是看编译器能否从实际参数表中获得足够的类型信息)来决定。下面来看一个例子。 public class demoGenMethods { // 定义泛型方法,有一个形式参数用类型参数T来定义 publicstatic <T> void showGenMsg(T ob, int n) { TlocalOb = ob; // 局部变量也可以用类型参数T来定义 System.out.println(localOb.getClass().getName()); } publicstatic <T> void showGenMsg(T ob) { System.out.println(ob.getClass().getName()); } publicstatic void main(String args[]) { Stringstr = "parameter"; Integerk = new Integer(123); //用两种不同的方法调用泛型方法 demoGenMethods.<Integer>showGenMsg(k, 1); showGenMsg(str); } } 程序中定义的两个泛型方法都是静态方法,这在泛型类中是不允许的。而且这两个泛型方法相互重载(参数的个数不同)。在方法体中,类型参数T的使用和泛型类中的使用是相同的。 再来看看如何调用这两个泛型方法: demoGenMethods.<Integer>showGenMsg(k,1); showGenMsg(str); 在第一种调用形式中,传入了一个实际类型:<Integer>,它表明类型参数是Integer类型。要注意它的写法,在这种情况下,不能省略作为前缀的类名,也就是不能写成这样: <Integer>showGenMsg(k,1); 由于传递了一个实际的类型参数Integer,所以编译器知道如何将方法内部的占位符T替换掉。不过需要注意,实际参数k的类型必须也是Integer型,否则编译器会报错。 第二种调用形式明显要简洁一些: showGenMsg(str); 由于实参str是String类型的,编译器已经有了足够多的信息知道类型参数T是String类型。程序的输出结果如下: 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()); } …… } 这样写当然没有错误,但多数程序员都会将这个泛型方法所需要的类型参数U写到类的头部,即让泛型类带两个参数: public class Generic<T, U>{ public void showGenMsg(U ob){ System.out.println(ob.getClass().getName()); } …… } 这样写,类的结构更为清晰。只有一种情况下必须在泛型类中再将方法声明为泛型方法:方法本身是静态的,那就无法像上面那样更改了。 欢迎拨打咨询热线: 020-38289118、4008852225 联系地址:广州市天河区科韵北路188号乐天大厦2楼(腾科IT教育)
|