一、泛型存在的意义
类型安全
编译时检查类型合法性,避免运行时ClassCastException
。
示例:未使用泛型时可能出现的错误:
List list=new ArrayList(); list.add("Hello"); Integer num=(Integer) list.get(0);// 运行时抛出异常
消除强制转换
自动处理类型转换,增强代码可读性:
List<String> list = new ArrayList<>();
list.add("Hello");
String str=list.get(0);// 无需显式转换
代码复用
通过泛型类/方法,实现逻辑与类型的解耦。
二、基础语法与使用
1. 泛型类
定义:类名后添加类型参数<T>
,T
代表任意类型:
public class Box<T> {private T content; public void set(T content) { this.content = content; } public T get() { return content; } }
使用:
Box<Integer> intBox = new Box<>();
intBox.set(123);
Integer value=intBox.get(); // 直接获取Integer类型
2. 泛型接口
定义: public
interface
Comparator<T> {
int compare(T o1, T o2);}
3. 泛型方法
独立于类的类型参数: public <T>
void
printArray(T[] array) {
for(T element : array) {
System.out.println(element);
}
}
三、通配符与边界
1. 通配符?
无界通配符:List<?>
表示未知类型的List,适合只读操作。
上界通配符:<? extends Number>
接受Number及其子类:
public double sum(List<? extends Number> list){ double sum=0; for(Number num : list) {sum += num.doubleValue();}return sum; }
下界通配符:<? super Integer>
接受Integer及其父类:
public void addNumbers(List<? super Integer> list){list.add(1);list.add(2);}
四、类型擦除与限制
1. 类型擦除机制
编译时擦除:泛型信息仅在编译阶段存在,运行时泛型类型会被擦除为原始类型(如Object
或定义的边界类型)。
List<String> stringList = new ArrayList<>();
List<Integer> intList = new ArrayList<>();
System.out.println(stringList.getClass() == intList.getClass()); // 输出 true
2. 泛型限制
无法实例化类型参数: public
class
Box<T> {
// 错误!不能直接实例化T// private T instance = new T();}
解决方案:通过传递Class<T>
类型:
public
class
Box<T> {
private T instance;
public Box(Class<T> clazz)throwsException {this.instance = clazz.newInstance();
}
}
不允许静态泛型参数:
public
class
Box<T> {
// 错误!静态变量不能使用泛型类型// private static T staticField;}
一、泛型类示例
场景:封装任意类型的数据容器
public class GenericBox<T> { private T content;public void setContent(T content){this.content = content; }public T getContent() {return content; } }// 使用示例GenericBox<String> strBox = new GenericBox<>(); strBox.setContent("Hello"); String value=strBox.getContent(); // 直接获取String类型,无需强制转换:ml-citation{ref="3,5" data="citationList"}
对比非泛型实现:
未使用泛型时需强制类型转换,存在运行时风险:
ObjectBox intBox=new ObjectBox();intBox.setContent(123);Integer num=(Integer) intBox.getContent(); // 若类型不匹配将抛出ClassCastException:ml-citation{ref="3" data="citationList"}
二、泛型方法示例
场景:独立于类的类型参数实现通用逻辑
public class ArrayUtils{// 泛型方法定义publicstatic <T> void printArray(T[] array) {
for (T element : array) { System.out.print(element + " "); }
}
}// 调用示例
Integer[] intArr = {1, 2, 3};
ArrayUtils.printArray(intArr); // 输出:1 2 3:ml-citation{ref="1,4" data="citationLis