题目
实现一个简单的泛型类:泛型盒子
信息
- 类型:问答
- 难度:⭐
考点
泛型类定义,类型安全,类型擦除
快速回答
实现一个泛型盒子类需要:
- 使用
<T>声明类型参数 - 用
T定义成员变量和方法参数/返回类型 - 提供存取方法保证类型安全
示例代码:
public class Box {
private T content;
public void put(T item) {
this.content = item;
}
public T get() {
return content;
}
}
## 解析
1. 泛型类实现原理
泛型允许在定义类/接口/方法时使用类型参数,使代码可处理多种数据类型而不丢失类型安全:
<T>:尖括号声明类型参数(惯例用单个大写字母)T content:用类型参数定义成员变量- 编译器在编译时进行类型检查,避免运行时类型转换错误
2. 完整代码示例
// 泛型类定义
public class Box<T> {
private T content;
// 存入方法(类型安全)
public void put(T item) {
this.content = item;
}
// 取出方法(无需强制转换)
public T get() {
return content;
}
public static void main(String[] args) {
// 创建String类型的盒子
Box<String> stringBox = new Box<>();
stringBox.put("Hello Generics");
String text = stringBox.get(); // 直接返回String类型
// 创建Integer类型的盒子
Box<Integer> intBox = new Box<>();
intBox.put(100);
int number = intBox.get(); // 直接返回Integer类型
}
}
3. 类型擦除机制
Java泛型在编译后执行类型擦除:
- 运行时
Box<String>和Box<Integer>都是原始类型Box - 成员变量
content变为Object类型 - 编译器自动插入类型转换代码:
(String)stringBox.get() - 擦除导致泛型类不能使用基本类型(需用
Integer替代int)
4. 最佳实践
- 命名规范:使用有意义的类型参数名(如
<E>元素,<K/V>键值) - 类型限定:需要特定能力时使用通配符或边界(如
<T extends Comparable>) - 避免混用原始类型:
Box rawBox = new Box();会绕过类型检查
5. 常见错误
| 错误示例 | 问题说明 |
|---|---|
Box<int> box = new Box<>(); | 不能使用基本类型(应改用Integer) |
T[] array = new T[10]; | 类型擦除后无法创建泛型数组 |
if(content instanceof T) | 运行时无法检测泛型类型 |
6. 扩展知识
- 泛型方法:独立于类的类型参数,如
<U> void inspect(U u){...} - 通配符:
Box<?>表示未知类型,Box<? extends Number>表示上边界 - 类型擦除的影响:重载方法时需注意签名冲突(如
void add(List<String>)和void add(List<Integer>)编译后签名相同)