美国上市公司,专注Java培训21年

Java中自定义泛型方法的使用


在学习java的过程中,我们常常会遇到泛型方法,泛型方法使得该方法能独立于类而产生变化。下面,我们可以写一个泛型方法,使其方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。

以下是一个基本的指导原则:

无论何时,只要你能做到,你就应该尽量使用泛型方法。也就是说,如果使用泛型方法可以取代将整个类泛型化,那么就应该只使用泛型方法,因为它可以使事情更清楚明白。另外,对于一个static的方法而言,无法访问泛型类的类型参数。所以,如果static方法需要使用泛型能力,就必须使其成为泛型方法。

下面是定义泛型方法的规则:

1)所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的<E>)。

2)每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。

3)类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。

4)泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像int,double,char的等)。

下面举一些泛型方法的示例:

/**

* public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。

* 只有声明了<T>等的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。

* <T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。

* 与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。

*/

public class GenericMethods {

public <T> void genericMethod1(T t){

System.out.println(t.getClass().getName());

}

public <T> T genericMethod2( Class<T> tClass ) throws InstantiationException ,

IllegalAccessException {

T t = tClass.newInstance();

return t;

}

public static <T> void genericMethod3( T[] inputArray ) {

// 输出数组元素

for ( E element : inputArray ){

System.out.printf( "%s ", element );

}

}

}

说明一下,定义泛型方法时,必须在返回值前边加一个<T>,来声明这是一个泛型方法,持有一个泛型T,然后才可以用泛型T作为方法的返回值或参数类型等。

泛型类是在实例化类的时候指明泛型的具体类型,而泛型方法是在调用方法的时候指明泛型的具体类型 。

泛型方法可以在任何地方和任何场景中使用,但是有一种情况是非常特殊的,当泛型方法出现在泛型类中时,我们再通过一个例子看一下:

/**

* 这是一个泛型类

*/

class GenericClassDemo<T> {

/**

* 这个不是泛型方法,只是使用了泛型类中已声明的T

*/

public void show1(T t){

System.out.println(t.toString());

}

/**

* 泛型方法,使用泛型E,这种泛型E可以为任意类型。可以类型与T相同,也可以不同。

* 由于下面的泛型方法在声明的时候声明了泛型<E>,因此即使在泛型类中并未声明泛型,

* 编译器也能够正确识别泛型方法中识别的泛型。

*/

public <E> void show2(E e){

System.out.println(e.toString());

}

/**

* 在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型;

* 可以与泛型类中声明的T不是同一种类型。

*/

public <T> void show3(T t){

System.out.println(t.toString());

}

}

泛型方法和可变参数

泛型方法与可变参数列表能很好地共存:

public class GenericMethodTest {

public <T> void printArgs( T... args ){

for(T t : args){

System.out.print(t + " ");

}

}

public static <T> List<T> toList(T... args){

List<T> result = new ArrayList<T>();

for(T item:args)

result.add(item);

return result;

}

public static void main(String[] args) {

GenericMethodTest gmt = new GenericMethodTest();

gmt.printArgs("A","B"); // A B

List ls = GenericMethodTest.toList("A");

System.out.println(ls); // [A]

ls = GenericMethodTest.toList("A","B","C");

System.out.println(ls); // [A,B,C]

}

}

静态方法使用泛型

静态方法无法访问类上定义的泛型,如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。即:如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法 。

public class GenericTest<T> {

/**

* 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明

* 即使静态方法不可以使用泛型类中已经声明过的泛型(需将这个方法定义成泛型方法)

* 如:public static void genericMethod(T t){..},此时编译器会提示错误信息:

* "StaticGenerator cannot be refrenced from static context"

*/

public static <T> void genericMethod(T t) {

// ...

}

}

版权声明:转载文章来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。


【免责声明】本文部分系转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,如涉及作品内容、版权和其它问题,请在30日内与我们联系,我们会予以重改或删除相关文章,以保证您的权益!

Java开发高端课程免费试学

大咖讲师+项目实战全面提升你的职场竞争力

  • 海量实战教程
  • 1V1答疑解惑
  • 行业动态分析
  • 大神学习路径图

相关推荐

更多
  • Java高级教程第二节:Java 集合框架
    Java高级教程第二节:Java 集合框架
    早在 Java 2 中之前,Java 就提供了特设类。比如:Dictionary, Vector, Stack, 和 Properties 这些类用来存储和操作对象组。 详情>>

    2019-05-30

  • Java高级教程第三节:Java 泛型
    Java高级教程第三节:Java 泛型
    Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。 详情>>

    2019-05-30

  • Java高级教程第四节:Java 序列化
    Java高级教程第四节:Java 序列化
    Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。 详情>>

    2019-05-30

  • Java高级教程第五节:Java 网络编程
    Java高级教程第五节:Java 网络编程
    # 包中 J2SE 的 API 包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。 详情>>

    2019-06-13

  • Java开班时间

    收起