温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

泛型通配符怎么用

发布时间:2026-07-15 10:28:03 来源:亿速云 阅读:93 作者:小樊 栏目:编程语言

在 Java 里,**泛型通配符(wildcard)**主要解决的是:

“泛型类型不确定,但又想安全地使用它” 的问题。

通配符只有三种:?? extends T? super T
下面用通俗解释 + 代码说明怎么用。


一、?:无界通配符(Unbounded Wildcard)

含义

不知道也不关心具体是什么类型,只要是一个泛型就行。

常见使用场景

  • 只读取,不关心具体类型
  • 方法参数只做“通用处理”

示例

void printList(List<?> list) {
    for (Object o : list) {
        System.out.println(o);
    }
}

✅ 可以接收:

List<String>
List<Integer>
List<Double>

❌ 不能往里加元素(除了 null):

list.add("abc"); // 编译错误

原因:编译器不知道 ? 到底是什么类型。


二、? extends T:上界通配符(Upper Bounded)

含义

类型是 T 或 T 的子类

典型场景:只读(Producer)

示例

void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
}

✅ 可以接收:

List<Integer>
List<Double>
List<Number>

❌ 不能添加元素:

list.add(1); // 编译错误

原因
? extends Number 可能是 List<Integer>,也可能是 List<Double>
Integer 不安全。

适合读取,不适合写入


三、? super T:下界通配符(Lower Bounded)

含义

类型是 T 或 T 的父类

典型场景:只写(Consumer)

示例

void addNumbers(List<? super Integer> list) {
    list.add(1);
    list.add(2);
}

✅ 可以接收:

List<Integer>
List<Number>
List<Object>

❌ 读取时只能当 Object

Object o = list.get(0); // 只能这样

原因
编译器只知道下限是 Integer,但不知道具体是什么父类。

适合写入,不适合读取


四、PECS 原则(重点,面试常考)

Producer → Extends,Consumer → Super

场景 用哪个
只往外取(生产者) ? extends T
只往里放(消费者) ? super T
又取又放 不用通配符,用具体泛型

经典例子(Collections.copy)

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

五、通配符 vs 泛型方法

什么时候用通配符?

✅ 如果只是使用泛型,不关心类型参数

void print(List<?> list)

什么时候用泛型方法?

✅ 需要返回具体类型类型之间有约束

<T> T getFirst(List<T> list) {
    return list.get(0);
}

六、一句话总结

  • ?:啥都行,只能读
  • ? extends T:只读(生产者)
  • ? super T:只写(消费者)
  • PECS 原则是核心

如果你愿意,我可以:

  • 集合 / 真实业务例子再讲一遍
  • 或帮你答 Java 泛型面试题
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI