java泛型设计

来源:互联网 发布:淘宝怎样装修店铺视频 编辑:程序博客网 时间:2024/06/06 15:01

自从java1.0发布以来,变化最大的部分就是泛型。泛型(generic)意味着编写的代码可以被很多不同类型的对象所重用。泛型可看作是普通类的工厂。

一.设计一个泛型类

public class Pair<T> {
private T first;
private T second;

public Pair() { this.first = null; this.second = null; }
public Pair( T first, T second){this.first = first; this.second = second; }

public T getFirst() { return first; }
public void setFirst(T first) { this.first = first; }

public T getSecond() { return second; }
public void setSecond(T second) { this.second = second; }
}

Pair类引入了一个类型变量T(需要时还可以用临近的字母U和S),用尖括号括起,放在类名后面。泛型类可以有多个类型变量。例如:

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


二.泛型方法

public class Pair

{

public static <T>  T getfirst(T a)

{

return a.hashCode;

}

}

从尖括号和类型变量可以看出这是一个泛型方法。类型变量放在修饰符(这里是public static)之后,返回类型的前面。泛型方法可以定义在泛型类中,也可以定义在普通类中。


三.泛型的使用

如果要对类型变量加以限定,如限制T为继承了A类且实现了B接口的类,可以这样定义:

public class Pair<T extends A & B> { ... }

extends后面可以有多个接口超类型,但至多只能有一个类。如果有一个类,它必须是列表中的第一个。限定类型用&分隔。

java会自动为为泛型类型提供一个原始类型(raw type)。原始类型的名字就是删去了类型参数的泛型类型的名字。类型变量被擦除(erased),并用其第一个限定类型(无限定类型的变量用Object)替换。


四.使用限制

1.不能用基本类型的类型参数,没有Pair<int>,只有Pair<Integer>。

2.不能在catch子句中使用类型变量,try{ ... } catch(T e) { ... }  这是错误的。但是在异常声明中可以使用类型变量,public  <T extends Throwable> void dowork( T t) throws T { ... }。

3.不能声明参数化类型的数组,如:Pair<String>[ ] pair = new Pair<String>(10); 这是不允许的。

4.不能实例化泛型类型,如: first = new T();

5.不能在静态域或方法中引用类型变量。 如:private static T first;


五.通配符类型

如果Manager是Employee的一个子类,那么千万不要认为Pair<Manager>是Pair<Employee>的子类,Pair<Employee> pe= new Pair<Manager>(); 是错误的。但特例是,总可以将参数化类型转化为一个原始类型。例如,Pair<Employee>是原始类型Pair的一个子类型。在同遗留代码衔接时,这个转换非常必要。当然泛型类可以扩展或实现其它泛型类,就这一点而言,与普通类没什么区别。这种设计使得在使用中非常不方便,因此java提供了一种巧妙的解决方案:通配符类型。如: Pair<? extends Employee>,类型Pair<Manager>可看作是Pair<? extends Employee>的子类型。

0 0