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

类型通配符

类型通配符用于处理不确定或受限的类型参数。

无界通配符

特点

  • 可匹配任意类型
  • 只能读取(作为 Object),不能添加(除 null)

使用示例

Java
// 无界通配符:可接收任意类型的 List
public void printList(List<?> list) {
    for (Object item : list) {
        System.out.println(item);  // 只能作为 Object 读取
    }
}

// 使用
printList(Arrays.asList("A", "B"));
printList(Arrays.asList(1, 2, 3));

不能添加元素:List 不知道具体类型,添加元素可能类型不匹配(除 null)。

上界通配符 <? extends T>

特点

  • 匹配 T 或 T 的子类
  • 只能读取,不能添加(除 null)

使用示例

Java
// 上界通配符:可接收 Number 或其子类
public double sum(List<? extends Number> list) {
    double total = 0;
    for (Number num : list) {
        total += num.doubleValue();  // 安全读取
    }
    return total;
}

// 使用
sum(Arrays.asList(1, 2, 3));            // List<Integer>
sum(Arrays.asList(1.0, 2.0, 3.0));      // List<Double>
sum(Arrays.asList(1L, 2L, 3L));         // List<Long>

不能添加元素:List<? extends Number> 不知道具体是 Integer 还是 Double,添加可能类型错误。

操作支持
读取✅ 作为 Number
添加❌ 不支持
添加 null✅ null 是所有类型

下界通配符 <? super T>

特点

  • 匹配 T 或 T 的父类
  • 可以添加 T 或 T 的子类
  • 读取只能作为 Object

使用示例

Java
// 下界通配符:可接收 Integer 或其父类
public void addNumbers(List<? super Integer> list) {
    list.add(1);      // ✅ 可以添加 Integer
    list.add(2);
    list.add(3);
}

// 使用
List<Number> numbers = new ArrayList<>();
addNumbers(numbers);  // List<Number>

List<Object> objects = new ArrayList<>();
addNumbers(objects);  // List<Object>
操作支持
添加 T 或子类
读取✅ 只能作为 Object

PECS 原则

Producer-Extends, Consumer-Super

  • Producer(生产者/读取):用 ? extends T
  • Consumer(消费者/写入):用 ? super T
Java
// 从集合读取 → extends
public void process(List<? extends Number> source) {
    Number n = source.get(0);  // 读取(Producer)
}

// 向集合写入 → super
public void add(List<? super Integer> target) {
    target.add(1);  // 写入(Consumer)
}

// 复制方法:src 读取(extends),dst 写入(super)
public static <T> void copy(
    List<? extends T> src,    // 生产者
    List<? super T> dest      // 消费者
) {
    for (T item : src) {
        dest.add(item);
    }
}

三者对比

通配符匹配范围读操作写操作
任意类型Object仅 null
<? extends T>T 及子类T仅 null
<? super T>T 及父类ObjectT 及子类

使用场景选择

场景通配符
只读取不写入<? extends T>
只写入不读取<? super T>
读取和写入都需要使用具体类型 <T>
不关心具体类型

要点总结

  • PECS:Producer 用 extends,Consumer 用 super
  • 需要读写都用具体类型而非通配符

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

← 上一篇 类型擦除
下一篇 → Java Class对象获取
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

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

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