一、痛点:没有泛型的世界
java
List list = new ArrayList(); // 原始类型
list.add("Hello");
list.add(100); // 允许不同类型混入
// 运行时崩溃风险!
String str = (String) list.get(1); // ClassCastException!
问题:类型不安全、需显式强制转换、易发运行时错误。
二、泛型核心概念与应用
1. 泛型类:封装通用逻辑
java
public class Box<T> { // T为类型参数
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content; // 无需强制转换
}
}
// 使用
Box<String> stringBox = new Box<>();
stringBox.setContent("Safe");
String value = stringBox.getContent(); // 自动类型推断
2. 泛型接口:统一行为契约
java
public interface Mapper<T, R> {
R map(T input); // T输入类型,R返回类型
}
// 实现字符串转整数
Mapper<String, Integer> strToIntMapper = input -> Integer.parseInt(input);
int num = strToIntMapper.map("123"); // 安全转换
3. 泛型方法:独立类型操作
java
public class ArrayUtils {
// 交换数组中任意位置元素
public static <T> void swap(T[] array, int i, int j) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
// 使用
String[] words = {"Hello", "World"};
ArrayUtils.swap(words, 0, 1); // 自动推断T为String
三、通配符:灵活的类型协变
java
// 上限通配符:处理Number及其子类
public double sumList(List<? extends Number> list) {
return list.stream().mapToDouble(Number::doubleValue).sum();
}
// 下限通配符:兼容Integer及其父类
public void addIntegers(List<? super Integer> list) {
list.add(42); // 安全写入
}
四、类型擦除:泛型的实现机制
泛型信息在编译后擦除,替换为原生类型:
java
// 编译前
List<Integer> intList = new ArrayList<>();
// 编译后(等效)
List intList = new ArrayList(); // 类型参数消失
影响:运行时无法获取泛型类型参数(如T.class非法)。
五、实际应用场景
- 集合框架:
ArrayList<E>,HashMap<K,V>确保元素类型一致 - 函数式接口:
Function<T,R>明确输入输出类型 - 工具类:
Collections.sort()通用排序算法 - 避免重复:通用DAO设计
java
public interface CrudRepository<T, ID> {
T findById(ID id);
void save(T entity);
}
避坑提示:不可直接实例化泛型类型参数(new T()非法),可通过工厂模式或Class.newInstance()解决。
结语
Java泛型如同代码的“类型契约”,在编译期筑起安全屏障,结合通配符实现灵活类型协作。理解类型擦除机制可规避运行时陷阱。善用泛型,可大幅提升代码健壮性与复用性,是Java开发者必备高阶技能。
关键价值:
✅ 编译时类型检查
✅ 消除显式强制转换
✅ 提升算法/容器复用性
✅ 设计更清晰的API契约
175

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



