一、泛型核心:类型参数化
泛型允许在定义类、接口或方法时使用类型参数(如<T>),使用时指定具体类型(如<String>)。编译器据此进行类型检查。
java
// 泛型类定义
public class Box<T> {
private T content;
public void set(T content) { this.content = content; }
public T get() { return content; }
}
// 使用示例:类型安全保证
Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get(); // 无需强制转换,避免ClassCastException
// stringBox.set(100); // 编译错误!类型不匹配
二、类型擦除:泛型的实现机制
Java 泛型是编译期特性。运行时,泛型类型信息被擦除:
- 无界类型参数(
<T>) →Object - 有界类型参数(
<T extends Number>) → 边界类型(Number)
java
// 编译后等效代码示例
public class Box {
private Object content;
public void set(Object content) { ... }
public Object get() { ... }
}
三、边界限定:精确控制类型范围
使用extends约束类型参数的上界,确保类型具备某些能力。
java
public <T extends Number & Comparable<T>> T max(T a, T b) {
return (a.compareTo(b) > 0) ? a : b;
}
// 可调用:max(10, 20); max(3.5, 2.1);
// 不可用:max("A", "B"); // String不满足Number边界
四、通配符:灵活的子类型处理
通配符? 增强 API 灵活性,处理未知泛型类型:
- 上界通配符
<? extends T>:支持读取(协变),如List<? extends Number> - 下界通配符
<? super T>:支持写入(逆变),如List<? super Integer>
java
// PECS 原则示例:Producer-Extends, Consumer-Super
public void copy(List<? extends Number> src, List<? super Number> dest) {
for (Number num : src) {
dest.add(num); // 安全写入
}
}
五、泛型方法:独立于类的类型参数化
在方法签名中声明类型参数,作用域仅限于该方法。
java
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
// 使用:compare(new Pair<>("A", 1), new Pair<>("B", 2));
关键实践:
- 优先使用泛型集合:
List<String>替代原始List。 - 警惕数组与泛型:Java 不支持创建泛型数组(
new T[size]非法)。 - 利用
Class<T>参数:运行时获取类型信息(如T.class.newInstance())。 - 类型推断:善用
<>钻石操作符(Java 7+)。
结语: Java 泛型通过编译时类型检查消除强制转换错误,大幅提升代码健壮性。深入理解类型擦除、通配符和边界机制,能有效设计高复用、强类型的安全 API,是进阶 Java 开发的核心能力。

被折叠的 条评论
为什么被折叠?



