泛型让你编写由类型参数化的类和方法,使得相同的代码可以处理多种类型,同时保持编译时类型安全。这就是参数多态 — "一种形状,任何类型。"
它们解决的问题
java
// Without generics: untyped, needs casts, can break at runtime
();
list.add();
(String) list.get();
// With generics: type is known and checked at compile time
List<String> list = new ArrayList<>();
list.add("hi");
String s = list.get(0); // no cast; list.add(42) won't compile
class Box<T> { // T is a type parameter
private T value;
Box(T value) { this.value = value; }
T get() { return value; }
}
Box<Integer> b = new Box<>(42); // T = Integer, checked at compile time
int n = b.get(); // no cast needed
<T extends Comparable<T>> // bounded: T must be comparable
List<? extends Number> // covariance: accept List<Integer>, List<Double>
Java在运行时会擦除泛型类型(类型擦除)— 你不能执行 new T() 或 instanceof List<String>。C++ 模板和 C# 泛型的行为不同(单态化/实具化类型)。
泛型同时提供了可复用性和安全性:一个 List<T> 可以服务于每种元素类型,编译器会捕捉那些否则会导致运行时崩溃的类型错误。
它们消除了不安全的类型转换,是集合框架的基础,使代码既更具可复用性,又更难被误用。