Java 泛型教程

更新于 2025-12-28

Jakob Jenkov 2024-08-03

Java 泛型使我们在某些情况下能够获得类型安全,这些情况指的是那些原本被设计为可处理任意类型的类和方法,如果不使用泛型,则只能处理 Object 类型的实例。例如,如果没有 Java 泛型,Java ListJava SetJava Map 等接口都将只能操作 Object 实例。而通过 Java 泛型,你可以创建只处理特定类型的 ListSetMap 实例,比如一个字符串列表(List<String>),而不是一个对象列表(List<Object>),从而在代码中获得更高的类型安全性。

Java 泛型通过向类、接口、方法和变量添加类型参数来实现这一功能。但前提是,你希望添加类型参数的类、接口、方法或变量本身必须被设计为支持泛型类型参数。

Java 内置的许多工具类和接口都支持泛型类型参数。本 Java 泛型教程将展示如何在这些类中使用泛型类型参数的一些示例。一旦你看过几个例子,就能掌握泛型类型参数的一般用法。

你也可以设计自己的类、接口和方法以支持 Java 泛型——也就是说,让它们能够接受类型参数。本教程也会展示如何做到这一点。

Java 泛型示例

Java 泛型和类型参数听起来有点抽象,让我们来看一个简单的 Java 泛型示例。

List 接口表示一个 Object 实例的列表。这意味着我们可以向 List 中放入任何对象。例如:

List list = new ArrayList();
list.add(new Integer(2));
list.add("a String");

由于可以添加任意对象,因此从列表中取出对象时,你也必须进行强制类型转换。例如:

Integer integer = (Integer) list.get(0);
String string = (String) list.get(1);

但实际上,我们经常只会在集合中使用单一类型。例如,你可能只存储 String 对象或其他某种特定类型,而不会像上面那样混合不同类型。

通过 Java 泛型特性,你可以限定集合的类型,从而限制可以插入到集合中的对象类型。此外,你也不需要再对从集合中获取的值进行强制类型转换。以下是使用 Java 泛型特性的示例:

List<String> strings = new ArrayList<String>();
strings.add("a String");
String aString = strings.get(0);

是不是很简洁?


Java 泛型类型推断

Java 7 对泛型特性进行了增强。从 Java 7 开始,Java 编译器可以根据变量所赋值的集合自动推断出其类型。下面是一个 Java 7 泛型示例:

List<String> strings = new ArrayList<>();

注意 ArrayList 的泛型类型被省略了,只保留了 <>,这有时也被称为“菱形操作符”(diamond operator)。当你只写一个菱形操作符作为泛型类型时,Java 编译器会假定所实例化的类具有与赋值变量相同的类型。在上面的例子中,就是 String,因为 List 变量的类型被指定为 String


Java 泛型 for 循环

Java 5 引入了一种新的 for 循环(也称为 “for-each” 循环),它与泛型集合配合得非常好。示例如下:

List<String> strings = new ArrayList<String>();
// ... 向 strings 列表中添加一些 String 实例 ...

for(String aString : strings) {
    System.out.println(aString);
}

这个 for-each 循环会遍历 strings 列表中所有的 String 实例。每次迭代时,下一个 String 实例会被赋值给变量 aString。相比传统的 while 循环(需要手动调用 Iterator.next() 来获取下一个元素),这种写法更简洁。

关于泛型 for 循环(即“for each 循环”)的更多细节,请参阅 Java 泛型 for 循环教程


Java 集合中的泛型

Java 泛型常用于 Java Collections API 中的数据结构。例如,你可以将 Java 泛型与 ListSetMap 一起使用,具体说明请参见以下文章:


泛型不仅限于集合

当然,泛型不仅可以用于 Java 集合类。

你也可以在自己的类中使用 Java 泛型。关于如何在自定义类中使用 Java 泛型的详细说明,请参阅以下教程:

你还可以使用 Java 泛型实现 Java Iterable 接口。具体实现方式请参阅:


Java 泛型通配符(Wildcards)

Java 泛型通配符允许你不仅指定某个类或集合的确切泛型类型,还可以指定该类型可以是给定类型的超类子类。Java 泛型通配符的详细说明请参见:


更多 Java 泛型教程

要全面理解 Java 泛型的工作原理,你需要学习以下主题: