简单描述泛型以及泛型的应用

一,概述:

泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。

什么是泛型

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

泛型的本质是为了参数化类型。这种参数类型可以用在类、接口和方法中,分别被称为

泛型类泛型接口泛型方法

泛型方法的益处:

 

泛型方法使得该方法能独立于类而产生变化。我们可以写一个泛型方法,该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。

 

二,基本的指导原则:

 

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

 

三,定义泛型方法的规则: 

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

 

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

 

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

 

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

 


/**

 * 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) {

        // ...

    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值