题目
实现一个泛型盒子类并解释类型擦除
信息
- 类型:问答
- 难度:⭐
考点
泛型类定义,类型擦除,类型安全
快速回答
实现步骤:
- 定义泛型类:
public class Box<T> {...} - 添加私有字段:
private T content; - 实现泛型方法:
public void setContent(T content)和public T getContent()
类型擦除要点:
- 编译后泛型类型会被替换为 Object
- 编译器自动插入类型转换代码
- 运行时无法获取泛型的具体类型
1. 泛型类实现
以下是完整的泛型盒子类实现:
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 Generics");
String value = stringBox.getContent(); // 无需强制转换
Box<Integer> intBox = new Box<>();
intBox.setContent(100);
int num = intBox.getContent(); // 自动拆箱3. 类型擦除原理
编译后代码实际变为:
public class Box {
private Object content; // 类型参数T被擦除为Object
public void setContent(Object content) {
this.content = content;
}
public Object getContent() {
return content;
}
}编译器会自动插入类型转换:String value = (String)stringBox.getContent();
4. 最佳实践
- 使用有意义的类型参数名:如 <T>、<E>、<K,V>
- 优先使用泛型方法:当方法逻辑独立于类泛型时
public <U> void inspect(U param) {...} - 避免原生类型:
Box rawBox = new Box(); // 危险!会绕过类型检查
5. 常见错误
- 类型不匹配:
Box<Integer> box = new Box<>(); box.setContent("abc"); // 编译错误! - 基本类型不可用:
Box<int> box; // 错误!必须使用包装类Integer - 运行时类型查询失效:
if (stringBox instanceof Box<String>) // 编译错误!
6. 扩展知识
- 通配符:
Box<?>表示未知类型,Box<? extends Number>表示上界限定 - 类型擦除的影响:
- 不能创建泛型数组:
new T[10] // 错误 - 不能抛出或捕获泛型异常
- 不能创建泛型数组:
- 类型安全的好处:
- 编译时发现类型错误
- 消除代码中的强制类型转换