一、泛型类的基本概念
1. 什么是泛型类
泛型类是指使用类型参数定义的类,可以在类定义时不指定具体类型,而在实例化时指定。
2. 泛型类的作用
-
类型安全:编译时检查类型匹配
-
消除强制转换:减少运行时ClassCastException风险
-
代码复用:同一套逻辑可适用于多种类型
-
提高可读性:代码意图更明确
二、泛型类的基本语法
1. 定义泛型类
// T是类型参数,可以是任何非关键字标识符
public class Box<T> {private T content;public void setContent(T content) {this.content = content;}public T getContent() {return content;}
}
2. 使用泛型类
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String str = stringBox.getContent(); // 不需要强制转换Box<Integer> intBox = new Box<>();
intBox.setContent(123);
int num = intBox.getContent(); // 自动拆箱
三、泛型类的多类型参数
public class Pair<K, V> {private K key;private V value;public Pair(K key, V value) {this.key = key;this.value = value;}public K getKey() { return key; }public V getValue() { return value; }public void setKey(K key) { this.key = key; }public void setValue(V value) { this.value = value; }
}// 使用示例
Pair<String, Integer> pair = new Pair<>("Age", 25);
String key = pair.getKey();
int value = pair.getValue();
四、泛型类的类型边界
1. 上界通配符(extends)
public class NumberBox<T extends Number> {private T number;public double getDoubleValue() {return number.doubleValue(); // 可以调用Number的方法}
}// 只能使用Number及其子类
NumberBox<Integer> intBox = new NumberBox<>();
NumberBox<Double> doubleBox = new NumberBox<>();
// NumberBox<String> stringBox = new NumberBox<>(); // 编译错误
2. 多重边界
public class MultiBound<T extends Number & Comparable<T> & Serializable> {// T必须是Number的子类,且实现了Comparable和Serializable
}
五、泛型类的继承关系
1. 泛型类可以继承非泛型类
public class GenericChild<T> extends NonGenericParent {// ... }
2. 泛型类可以继承泛型类
public class Child<T> extends Parent<T> {// 使用相同的类型参数 }public class StringChild extends Parent<String> {// 指定具体类型 }
六、泛型类与静态成员
public class StaticGeneric<T> {// 静态成员不能使用类的类型参数// private static T staticField; // 编译错误// 静态方法可以定义自己的类型参数public static <E> E staticMethod(E input) {return input;} }
七、泛型类的类型擦除
Java泛型是通过类型擦除实现的,编译后会去除类型参数信息:
// 编译前 Box<String> box = new Box<>(); box.setContent("Hello");// 编译后(近似) Box box = new Box(); box.setContent((Object)"Hello"); String str = (String)box.getContent();
八、泛型类的高级用法
1. 通配符(?)
public void processList(List<?> list) {// 可以接受任何类型的Listfor (Object item : list) {System.out.println(item);}
}public void processNumberList(List<? extends Number> list) {// 接受Number及其子类的Listfor (Number num : list) {System.out.println(num.doubleValue());}
}
2. PECS原则(Producer-Extends, Consumer-Super)
// 生产者使用extends public void copyFrom(List<? extends Number> src, List<? super Number> dest) {for (Number num : src) {dest.add(num);} }
九、泛型类的限制
-
不能创建泛型数组
// T[] array = new T[10]; // 编译错误
-
不能实例化类型参数
// T obj = new T(); // 编译错误
-
不能用于静态上下文
// private static T staticField; // 编译错误
-
基本类型不能作为类型参数
// List<int> list = new ArrayList<>(); // 编译错误 // 必须使用包装类 List<Integer> list = new ArrayList<>();
十、泛型类的实际应用
1. 集合框架
List<String> strings = new ArrayList<>(); Map<Integer, String> map = new HashMap<>();
2. 自定义容器
public class Cache<T> {private Map<String, T> cacheMap = new HashMap<>();public void put(String key, T value) {cacheMap.put(key, value);}public T get(String key) {return cacheMap.get(key);}
}
3. 工具类
public class MathUtils {public static <T extends Number> double average(Collection<T> numbers) {double sum = 0.0;for (T num : numbers) {sum += num.doubleValue();}return sum / numbers.size();}
}
十一、总结
Java泛型类的主要特点:
-
通过类型参数实现通用编程
-
提供编译时类型安全检查
-
消除强制类型转换
-
支持类型边界限制
-
通过类型擦除实现
合理使用泛型类可以:
-
提高代码的类型安全性
-
增强代码的可读性和可维护性
-
减少重复代码
-
构建更灵活的API