Java--泛型程序设计语法

定义简单的泛型类:

public class Pair<T>{
    private T first;
    private T second;
    
    public T getFirst(){ return first; }
    public T getSecond(){ return second; }

    public void setFirst(T newVal){ first = newVal; }
    public void setSecond(T newVal){ second = newVal; }
}

Pair类引入一个新的类型变量,用尖括号(<>)括起来并放到类名的后面。泛型类可以有多个类型变量:

public class Pair<T,U>{...}

使用时,用具体的类型替换类型变量就可以实例化泛型类型:

Pair<String> p = new Pair<String>();
//Java SE7版本及以后,构造函数中可以省略泛型类型
Pair<String> p = new Pair<>();

换句话说,泛型类可以看作是普通类的工厂。

泛型方法:

泛型方法可以定义在普通类中,也可以定义在泛型类中。

class ArrayAlg{
    //定义泛型方法
    public static <T> T getMiddle(T[] a){
        return a[a.length/2];
    }
}
//调用泛型方法
String middle = ArrayAlg.<String>getMiddle("John","Q.","Public");
//方法调用中也可以省略类型参数
String middle = ArrayAlg.getMiddle("John","Q.","Public");

类型变量的限定:

有时候,类或方法需要对类型变量进行约束。如我们要实现一个泛型比较方法,那么只有实现了Comparable接口的类才可以进行比较。变量限制的语法如下:

public static <T extends Comparable> T min(T[] a){...}

现在,泛型的min()方法只能被实现了的Comparable接口的类的数组调用,否则会产生一个编译错误。

<T extends BoundingType>表示T应该是绑定类型的子类型,T和绑定类型可以是类,也可以是接口。

一个类型变量或通配符可以有多个限定,例如:

<T,U extends Comparable & Serializable>

限定类型用“&”分隔,类型变量用逗号分隔。

泛型类型的继承规则:

我们假设Manager(经理)是Employee(雇员)的一个子类,那么Pair<Manager>是Pair<Employee>的子类吗?不是!下面这样编写代码会得到一个错误:

Manager[] topHon = ...;
Pair<Employee> result = ArrayAlg.minmax(topHon);//错误

无论S与T是什么关系,通常Pair<S>与Pair<T>没有什么联系。

不要泛型和Java继承搞混,下面这样的代码显然正确:

Manager[] managerBuddies = {ceo, cfo}
Employee[] employeeBuddies = managerBuddies; //正确

永远可以将参数化类型转换为一个原始类型(因为类型擦除,见下一篇博客)。但要当心转换后可能会产生类型错误(类型不匹配但不会报错),例如:

Pair<Manager> managerBuddies = new Pair<>(ceo,cfo);
Pair rawBuddies = managerBuddies;
rawBuddies.setFirst(new File("huo");//很明显类型错误,但只会得到一个警告而不是错误

泛型类可以扩展或实现其他泛型类,这一点和普通类没有任何区别。例如ArrayList<T>实现了List<T>接口,一个ArrayList<Manager>可以被转化为一个List<Manager>。

泛型会有一些约束和限制,具体情况下篇讨论。

下一篇:泛型的约束和限制

猜你喜欢

转载自my.oschina.net/HuoQibin/blog/1622106