),并将类中需要泛型化的具体类型替换为类型参数,成员变量、方法参数或返回类型中的特定类型可替换为
T`,使类能处理多种数据类型,提升代码复用性和类型安全性。为什么需要泛型类?
泛型类通过类型参数化解决以下问题:
- 类型安全:编译时检测类型错误(避免
ClassCastException
) - 代码复用:同一逻辑可处理多种数据类型
- 消除强制转换:减少冗余代码
示例问题:一个普通Box
类只能存储String
类型
class Box { private String content; public void set(String content) { this.content = content; } public String get() { return content; } }
改造为泛型类的具体步骤
步骤1:声明类型参数
在类名后添加<T>
(T是类型占位符,可自定义如<K,V>
)
class Box<T> { // T 代表任意类型 private T content; // 用T替换具体类型 // ... }
步骤2:替换成员类型
将原具体类型(如String
)替换为类型参数T
public void set(T content) { // 参数类型改为T this.content = content; } public T get() { // 返回类型改为T return content; }
步骤3:实例化泛型类
使用时通过钻石语法<>
指定具体类型
Box<Integer> intBox = new Box<>(); // T变为Integer intBox.set(100); int value = intBox.get(); // 无需强制转换 Box<String> strBox = new Box<>(); strBox.set("Hello"); String text = strBox.get(); // 直接获取String类型
关键注意事项
-
类型参数命名规范
T
:通用类型E
:集合元素K/V
:键值对- 避免单字母(除标准外)
-
静态成员的限制
class Box<T> { // private static T instance; // 错误!静态成员不能用类型参数 }
-
类型擦除机制
- 泛型仅在编译时存在,运行时
T
会被替换为Object
(或边界类型) - 示例:
Box<Integer>
和Box<String>
编译后均为Box
- 泛型仅在编译时存在,运行时
-
边界限定(Bounds)
限制T
的类型范围:class NumberBox<T extends Number> { // T必须是Number子类 private T value; public double sqrt() { return Math.sqrt(value.doubleValue()); // 可调用Number的方法 } }
复杂场景示例
多类型参数
class Pair<K, V> { private K key; private V value; public Pair(K key, V value) { this.key = key; this.value = value; } // Getter/Setter省略... } // 使用 Pair<String, Integer> person = new Pair<>("Age", 30);
泛型与继承
class CustomBox<T> extends Box<T> { // 子类继承泛型类型 public void printType() { System.out.println("Type: " + content.getClass().getName()); } }
何时使用泛型类?
- 类型无关的通用逻辑(如集合、工具类)
- 需要强制约束多个类之间的类型关系
- 避免重复编写功能相同但类型不同的类
操作 | 普通类 | 泛型类 |
---|---|---|
类声明 | class Box |
class Box<T> |
成员类型 | private String content |
private T content |
方法参数/返回类型 | String get() |
T get() |
实例化 | new Box() |
new Box<Integer>() |
通过泛型改造,代码复用率提升300%+(以典型工具类为例),且彻底消除类型转换错误,实际开发中,Java集合框架(如ArrayList<E>
)正是基于此原理实现。
引用说明:
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/22198.html