首页 > 代码库 > 泛型程序设计

泛型程序设计

在JDK5.0之前:

public class ArrayList{
    public Object get(int i){...}
    public void add(Object o){...}
    ...
    private Object[] elementData;
}
这样实现有两问题。首先,当取得一个值的时候必须进行强制类型转换。

ArrayList files = new ArrayList();

...

String filename = (String)names.get(0);

此外,这里没有错误检查。可以向数组列表中添加任何类的对象。

files.add(new File("..."));

对于这个调用,编译和运行都不会出错。然而在其他地方,如果将get的结果强制类型转换为String类型,就会产生一个错误。
JDK5.0提供了一个更好的解决方案:类型参数(type parameter)。ArrayList类有一个类型参数用来指示元素的类型:ArrayList<String> files = new ArrayList<String>();

这将使代码具有更好的可读性。人们一看就知道这个数组列表中包含的是String对象,添加错误的类型会编译报错,取出元素也不需强制类型转换。类型参数的魅力在于,使得程序具有更好的可读性和安全性。

泛型类的自定义:

public class Pair<T>{
    private T first;
    private T second;
    public Pair(){
        first = null;
        second = null;
    }
    public T getFirst(){
        return first;
    }
    public T getSecond(){
        return second;
    }
    public void setFirst(T newValue){
        first = newValue;
    }
    public void setSecond(T newValue){
        second = newValue;
    }
}
    Pair类引入了一个类型变量T,用尖括号(<>)括起,并放在类名的后面。泛型类可以有多个类型变量,例如:public class Pair<T,U>{...}

泛型方法:

class ArrayAlg{
    public static <T> T getMiddle(T[] a){
	    return a[a.length/2];
	}
}
    这个方法是在普通类中定义的,而不是在泛型类中定义的。注意,类型变量放在修饰符(这里是public static)的后面,返回类型的前面。

    当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型:

    String[] names = {"John","Q","Public"};

    String middle = ArrayAlg.<String>getMiddle(names);(其中<String>可省略)

类型变量的限定:

    有时,类或方法需要对类型变量加以约束:

class ArrayAlg{
    public static <T extends Comparable> T min(T[] a){
	    if(a == null || a.length == 0){
		    return null;
	    }
	    T smallest = a[0];
	    for(int i=1;i<a.length;i++){
		    if(smallest.compareTo(a[i])>0){
		        smallest = a[i];
		    }
		}
	    return smallest;
	}
}

类型T要想有compareTo方法,必须继承Comparable接口。
一个类型变量或通配符可以有多个限定,如:T extends Comparable & Serializable。