文档

Java™ 教程-Java Tutorials 中文版
介绍
Trail: Bonus
Lesson: Generics

介绍

JDK 5.0 引入了 Java 编程语言的几个新扩展。其中之一是 generics (泛型) 的引入。

这条路径是对泛型的介绍。你可能熟悉其他语言的类似结构,最常见的是 C++ 模板。如果是这样,你会发现存在相似之处和重要差异。如果你不熟悉其他地方看起来相似的结构,那就更好了;你可以重新开始,而不必忘记任何误解。

泛型允许你抽象类型。最常见的示例是容器类型,例如 Collections 层次结构中的容器类型。

以下是此类的典型用法:

List myIntList = new LinkedList(); // 1
myIntList.add(new Integer(0)); // 2
Integer x = (Integer) myIntList.iterator().next(); // 3        

第 3 行的强制转换有点烦人。通常,程序员知道将哪种数据放入特定列表中。但是,强制转换是必不可少的。编译器只能保证迭代器返回 Object。要确保为 Integer 类型的变量赋值是类型安全的,需要强制转换。

当然,强制转换不仅引入了混乱。它还引入了运行时错误的可能性,因为程序员可能会弄错。

如果程序员可以实际表达他们的意图,并将列表标记为限制包含特定数据类型,该怎么办?这是泛型背后的核心理念。以下是使用泛型给出的程序片段的一个版本:

List<Integer> 
    myIntList = new LinkedList<Integer>(); // 1'
myIntList.add(new Integer(0)); // 2'
Integer x = myIntList.iterator().next(); // 3'

注意变量 myIntList 的类型声明。它指定这不仅是一个任意 List,还是一个 IntegerList,写成 List<Integer>。我们说 List 是一个带有 type parameter (类型形参) 的泛型接口 - 在这种情况下,Integer。我们还在创建列表对象时指定了类型形参。

另请注意,第 3 行的强制转换已经消失。

现在,你可能会认为我们所取得的成就就是去除了杂乱无章。我们将 Integer 作为第 1 行的类型形参,而不是第 3 行的强制转换为 Integer 。但是,这里有很大的不同。编译器现在可以在编译时检查程序的类型正确性。当我们说 myIntList 用类型 List<Integer> 声明时,这告诉我们一些关于变量 myIntList 的信息,无论它在何时何处被使用都保持为真,编译器将保证它。相比之下,强制转换告诉我们程序员认为代码中的单个点是正确的。

最终的效果,提高了可读性和稳健性,特别是在大型程序中。


Previous page: Generics
Next page: Defining Simple Generics