f泛型程序设计 (Generic programming) 意味着编写代码可以被很多不同的对象所重用。
在 Java 增加泛型类之前,泛型程序设计是用继承实现的。ArrayList 类只维护一个 Object 引用的数组:
1 | public class ArrayList{ |
这种方法有两个问题。当获取一个值时必须进行强制类型转换,
1 | ArrayList files = new ArrayList(); |
此外,这里没有错误检查。可以向数组列表中添加任何类的对象。
1 | files.add(new File("...")) |
对于这个调用,编译和运行都不会出错。然而在其他地方,如果将 get 的结果强制类型转换为 String 类型,就会产生一个错误。
泛型提供了一个更好的解决方案,类型参数 (type parameters)。ArrayList 类有一个类型参数用来指示元素的类型:
1 | ArrayList<String> files = new ArrayList<String>(); |
这使得代码具有更好的可读性。
Java SE 7 及以后的版本,构造函数中可以省略泛型类型:
ArrayList<String> files = new ArrayList<>();省略的类型可以从 变量的类型推断得出。
编译器可以很好地利用这个信息。当调用 get 时,编译器不需要进行强制转换,另外,编译器可以进行类型检查,避免插入错误类型的对象。使程序具有更好的可读性和安全性。
定义简单泛型类
一个泛型类 (generic class) 就是具有一个或多个类型变量的类。
1 | public class Pair<T> { |
Pair 类引入了一个类型变量 T,用尖括号括起来,放在类名后面。泛型类可以有多个类型变量。例如,可以定义 Pair 类,其中第一个域和第二个域使用不同的类型:
1 | public class Pair<T, U> {...} |
类定义中的类型变量指定方法的返回类型以及域和局部变量的类型。例如:
1 | private T first; // uses the type variable |
E 表示集合的元素类型;K 和 V 分别表示关键字与值的类型;T :表示 “任意类型”,若泛型类有多个时可以用U和S