泛型

来源:互联网 发布:seo团队 编辑:程序博客网 时间:2024/06/06 01:16

泛型(generic)是指参数化类型的能力。可以定义带泛型类型的类或方法,随后编译器会用具体的类型来替换它(泛型实例化)。使用泛型的主要优点是能够在编译时,而不是在运行时检测出错误。(泛型类型必须是引用类型。)

一、泛型类和泛型接口

这里写图片描述

注意:

  1. 创建一个字符串堆栈可以使用new GenericStack< String >(),这可能会让我们误认为构造方法应该被定义为public GenericStack< E >(),这是错误的,正确的应该是public GenericStack()。
  2. 有时候,泛型类可能会有多个参数。在这种情况下,应将所有参数一起放在尖括号中,并用逗号分隔开,如< E1, E2, E3 >
  3. 可以定义一个类或一个接口作为泛型或者接口的子类型。例如,Java API中的public class String implementes Comparable< String >

二、泛型方法

  1. 为了定义一个类为泛型类型,需要将泛型类型放到类名之后,例如GenericStack< E >,为了定义一个方法为泛型类型,需要将泛型放到方法返回值之前,例如< E > void max(E o1, Eo2)。
  2. 可以将泛型指定为另外一种类型的子类型,这样的泛型称为受限的(bounded)。例如< E extends GeometricObject >,特殊的非受限泛型类型< E >和< E extends Object >是一样的。
/** * 泛型方法 */public class GenericMethodDemo {    public static void main( String[] args ) {        Integer[] integers = {1,2,3,4,5};        print(integers);    }    public static < E > void print( E[] list ) {        for ( int i = 0 ; i < list.length ; i++ ) {            System.out.print( list[ i ] + " " );        }        System.out.println();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

三、通配泛型

尽管Integer是Number的子类型,但是GenericStack< Integer >不是GenericStack< Number >的子类型。为了解决这个问题,可以使用通配泛型(GenericStack< ? extends Number >)。通配泛型有三种形式:?、? extends T、? super T,其中T是某个泛型类型。第一种形式 ? 称为非受限通配,它和 ? extends Object 是一样的;第二种形式 ? extends T 称为受限通配,标示T或T的一个未知子类型;第三种形式 ? super T 称为受限通配,标示T或T的一个未知父类型。

这里写图片描述

四、泛型消除

泛型是使用一种称为类型消除(type erasure)的方法实现的。编译器使用泛型类型信息编译代码,但是随后会消除它。因此,泛型信息在运行时是不可用的,这种方法可以使泛型代码向后兼容使用原始类型的遗留代码。

五、泛型限制

  1. 不能使用泛型参数创建实例,即不能使用new E()
  2. 不能使用泛型参数创建数组,即不能使用new E[]
  3. 异常类不能是泛型的,因为泛型类不能扩展java.lang.Throwable。
  4. 在静态环境下不允许类的参数是泛型类型。由于泛型类的所有实例都有相同的运行时类,所以泛型类的静态变量和方法是被它的所有实例所共享的。因此,在静态方法、数据域或者初始化语句中,为了类而引用泛型类型参数是非法的。例如:
    public class Test<E> {    public static E o1; // Illegal    public static void m(E o1) { // Illegal    }    static {        E o2; // Illegal    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10