Java 泛型

2017/12/06 Java

Java 泛型

泛型是类型参数化,用变量来表示类型。

泛型的定义

//Generics class
class CA<T>{
    private T t;
    Test(T t){
        this.t=t;
    }
}

//Generics method
public <T> void show(){
    //...
}

类型擦除和泛型翻译

泛型只是为了完善java体系,增加程序员编程的便捷性以及安全性而创建的一种机制,在JAVA虚拟机中对应泛型的都是确定的类型,在编写泛型代码后,java虚拟中会把这些泛型参数类型都擦除,用相应的确定类型来代替,代替的这一动作叫做类型擦除,而用于替代的类型称为原始类型,在类型擦除过程中,一般使用第一个限定的类型来替换,若无限定则使用Object。

泛型翻译

//Generics class
class CA<T>{
    private T;
}
//翻译后
class CA{
    private Object;
}
//类型限定 
class CA<? extends Comparable>{
    private T
}
//翻译后
class CA{
    private Comparable t;
}

泛型限定

泛型限定是通过?(通配符)来实现的。表示可以接受任意类型。

public void print(ArrayList<?> al){
    Iterator<?> it=al.iterator();
    while(it.hasNext()){
        System.out.println(it.next());
    }
}

public <T> void print(ArrayList<T> al){
    Iterator<T> it=al.iterator();
    while(it.hasNext()){
        T t=it.next();
        System.out.println(t);
    }
}

区别在于,用?不能作为类型使用,用T可以作为类型来使用。 ` ? extends SomeClass表示可以接受SomeClass及子类。 ? super SomeClass还没来得及可以接受SomeClass和其父类类型。T extends Comparable & Serializable`表示可以接受多种类型限定,写在前面的类型就是类型擦除后的类型。

泛型的基本约束

  • 泛型的类型参数必须是类的引用,不能用基本类型。
  • 泛型是类型的参数化,使用时可以用作不同类型。
  • 泛型的类型参数可以有多个。如:public <T,E> void show()
  • 泛型可以使用extends,super,?对类型进行限定。
  • 存在类型擦除机制 ,所以运行时类型查询只能用于原始类型。instanceof,getClass(),强制类型转换等。如:instanceof(Pair<Emplyee>)类型擦除后就是instanceof(Pair)
  • 不能创建参数化类型的数组。
    Pair<String>[] table=new Pair<String>[10];
    Object[] t=table;
    t[0]=new Pair<Emplye>();//可以存入,但是取出的时候会出现ClassCastException
    
  • 不能实例化类型变量。
    T t =new T();
    T.class         //类型擦除后这样的写法没有意义
    
  • 不能在静态域和方法中出现参数类型,静态方法不能有泛型是因为编译的时候泛型的类型是不能确定的。
Show Disqus Comments

Search

    Table of Contents