Java泛型
目录
Java泛型
Java泛型是Java 5引入的一项重要特性,旨在增强类型安全、减少代码冗余,并支持更灵活的代码设计。以下是对泛型的详细介绍及使用指南:
一、泛型核心概念
泛型允许在
类、接口、方法
中使用
类型参数
(如
<T>
),使得代码可以处理多种数据类型,而无需重复编写逻辑。
解决的问题
- 类型安全
:避免运行时
ClassCastException
。 - 消除强制类型转换 :编译器自动处理类型转换。
- 代码复用 :同一逻辑可处理不同类型的数据。
二、泛型的基本使用
1. 泛型类
通过
<T>
定义类型参数,类内部可用
T
作为类型。
public class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
// 使用示例
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String value = stringBox.getContent(); // 无需强制转换
2. 泛型接口
接口定义类型参数,实现类可指定具体类型。
public interface List<T> {
void add(T element);
T get(int index);
}
// 实现示例
public class StringList implements List<String> {
// 实现方法时使用String代替T
}
3. 泛型方法
在方法返回类型前声明类型参数
<T>
,独立于类的泛型。
public <T> void printArray(T[] array) {
for (T item : array) {
System.out.println(item);
}
}
// 调用示例
Integer[] intArr = {1, 2, 3};
printArray(intArr); // 自动推断T为Integer
三、类型通配符
用于增强泛型的灵活性,处理未知类型。
1. 无界通配符 <?>
表示任意类型,常用于只读操作。
public void printList(List<?> list) {
for (Object item : list) {
System.out.println(item);
}
}
2. 上界通配符 <? extends T>
接受
T
及其子类,适合读取数据(Producer)。
public double sum(List<? extends Number> list) {
double sum = 0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum;
}
3. 下界通配符 <? super T>
接受
T
及其父类,适合写入数据(Consumer)。
public void addNumbers(List<? super Integer> list) {
list.add(1);
list.add(2);
}
PECS原则(Producer Extends, Consumer Super)
- 生产者(读取数据)
:使用
<? extends T>
。 - 消费者(写入数据)
:使用
<? super T>
。
四、类型擦除与限制
Java泛型通过
类型擦除
实现,编译时擦除泛型信息,替换为原生类型(如
Object
)或边界类型。
关键限制
- 无法实例化类型参数
:
new T()
是非法的。 - 不能使用基本类型
:如
List<int>
需改为List<Integer>
。 - 静态上下文限制 :静态方法/变量不能引用类的类型参数。
- 泛型数组问题
:不能直接创建泛型数组(如
new T[10]
)。
五、泛型高级应用
1. 多类型参数
类或方法可定义多个类型参数。
public class Pair<K, V> {
private K key;
private V value;
// 构造方法、Getter/Setter...
}
2. 边界类型(Bounded Type)
限制类型参数的范围。
public <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) > 0 ? a : b;
}
六、应用场景
- 集合框架
:如
List<String>
,Map<Integer, String>
。 - 工具类 :通用算法(排序、查找)可处理多种类型。
- 回调机制
:如
Comparator<T>
接口。
七、示例代码
泛型类与继承
public class NumericBox<T extends Number> {
private T number;
public NumericBox(T number) {
this.number = number;
}
public double square() {
return number.doubleValue() * number.doubleValue();
}
}
// 使用示例
NumericBox<Integer> intBox = new NumericBox<>(5);
System.out.println(intBox.square()); // 输出25.0
通配符实践
public static void copy(List<? extends Number> src, List<? super Number> dest) {
for (Number num : src) {
dest.add(num);
}
}
八、总结
- 优点 :类型安全、减少重复代码、提高可读性。
- 注意 :类型擦除的影响、通配符的正确使用、边界限制。
掌握泛型能显著提升Java代码的质量和灵活性,尤其在集合操作和通用工具类设计中表现突出。