全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-10 10 分钟 ✍️ juanwangdev

泛型最佳实践

泛型使用遵循一些最佳实践,可提高代码质量和类型安全。

类型参数命名约定

Java
// 推荐:使用标准命名
public class Box<T> {}           // Type,任意类型
public class List<E> {}          // Element,集合元素
public class Map<K, V> {}        // Key, Value
public class Comparator<T> {}    // Type
public class Function<T, R> {}   // Type, Result
命名用途
TType,通用类型
EElement,集合元素
KKey,键
VValue,值
NNumber,数值
RResult,返回类型

避免单字母外命名:保持代码一致性,便于理解。

PECS 原则

Producer-Extends, Consumer-Super:

Java
// 生产者(读取):用 extends
public void process(List<? extends Number> source) {
    Number n = source.get(0);  // 读取
}

// 消费者(写入):用 super
public void add(List<? super Integer> target) {
    target.add(1);  // 写入
}

// 复制方法
public static <T> void copy(
    List<? extends T> src,    // 生产者
    List<? super T> dest      // 消费者
) {
    for (int i = 0; i < src.size(); i++) {
        dest.set(i, src.get(i));
    }
}

PECS 记忆:"Get(读取)用 extends,Put(写入)用 super"。

避免使用原始类型

Java
// 错误:使用原始类型
List list = new ArrayList();  // 无泛型,类型不安全
list.add("Hello");
list.add(100);  // 编译通过,运行时可能出错

// 正确:使用泛型
List<String> list = new ArrayList<>();
list.add(100);  // 编译错误

原始类型警告:编译器警告 "List is a raw type",应消除。

消除泛型警告

Java
// 错误:泛型警告未处理
List list = new ArrayList();  // 警告

// 正确1:使用泛型
List<String> list = new ArrayList<>();

// 正确2:明确转型时抑制警告
@SuppressWarnings("unchecked")
List<String> list = (List<String>) rawList;

抑制警告原则:仅在明确知道转型安全时使用,注释说明原因。

不要在静态成员使用类泛型参数

Java
// 错误:静态成员不能使用类泛型参数
public class Box<T> {
    private static T value;  // 错误
    public static T method() { return null; }  // 错误
}

// 正确:静态方法定义自己的泛型参数
public class Box<T> {
    public static <E> E method(E item) {
        return item;
    }
}

优先泛型方法而非通配符

Java
// 方式1:通配符
public static void process(List<?> list) {
    // 只能作为 Object 处理
}

// 方式2:泛型方法(推荐)
public static <T> void process(List<T> list) {
    T first = list.get(0);  // 类型安全
    list.add(first);        // 可添加
}

泛型方法优势:保持具体类型,可读写操作。

使用泛型消除转型

Java
// 错误:手动转型
List list = new ArrayList();
list.add("Hello");
String s = (String) list.get(0);  // 转型

// 正确:泛型消除转型
List<String> list = new ArrayList<>();
list.add("Hello");
String s = list.get(0);  // 无需转型

避免过度泛型化

Java
// 过度泛型化:不需要泛型
public class Id<T> {
    private T value;
    public T getValue() { return value; }
}

// Id<Integer> 和 Id<String> 功能完全相同
// 泛型没有带来实际价值

// 适当泛型化:泛型有意义
public class Box<T> {
    private T value;
    // T 在类中确实发挥作用
}

基本类型使用包装类

Java
// 错误:泛型不支持基本类型
List<int> list = new ArrayList<int>();  // 编译错误

// 正确:使用包装类
List<Integer> list = new ArrayList<>();

泛型与异常

Java
// 错误:不能抛出泛型异常
public class MyException<T> extends Exception {}  // 错误

// 错误:catch 不能用泛型
public void method() {
    try { }
    catch (T e) {}  // 错误
}

// 正确:方法签名可用泛型
public <T extends Exception> void method() throws T {}

要点总结

  • 类型参数命名:T、E、K、V 等标准命名
  • PECS:Producer 用 extends,Consumer 用 super
  • 避免原始类型,使用泛型保证类型安全
  • 静态成员不能使用类泛型参数
  • 优先泛型方法而非通配符
  • 使用泛型消除手动转型
  • 基本类型使用包装类替代
  • 避免过度泛型化,泛型应带来实际价值
  • 泛型不能用于异常类和 catch

📝 发现内容有误?点击此处直接编辑

← 上一篇 泛型方法
下一篇 → 泛型类
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库