You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java泛型中以<? extends Number>声明的List参数类型是什么?

public static void print(List<? extends Number> list) {
    for (Number n : list)
      System.out.print(n + " ");
    System.out.println();
}

public static void main(String[] args) {
    ArrayList<Integer> al = new ArrayList<>();
    print(al);
}

关于入参类型的问题

你的认知有偏差,list的实际泛型类型并不是Number:

  • 方法定义里的List<? extends Number>是泛型上界通配符约束,意思是该入参可以接收所有「元素类型为Number或Number子类」的List实例,具体实际类型由调用方传入的参数决定,你示例中传入的是ArrayList<Integer>,那本次调用时list的实际类型就是ArrayList<Integer>
  • 你困惑的for循环可以用Number接收元素,本质是Java里父类引用指向子类实例的向上转型规则,不管list的元素是Integer、Double还是Long,都属于Number的子类,转型完全合法,和list本身的泛型类型没有冲突。
  • 额外补充区分点:如果把方法入参改成List<Number>,你反而没法传入ArrayList<Integer>了,因为Java泛型不支持协变,List<Integer>和List<Number>不存在继承关系,这就是上界通配符存在的核心意义。

关于实际开发的使用频率

这个写法非常常用,属于Java泛型的标准基础用法,完全符合PECS(Producer Extends Consumer Super)开发规范:

  • 当你写的工具方法只需要从集合中读取元素(集合作为生产者提供元素),不需要往集合里新增元素时,用? extends 上界可以大幅提高方法的通用性,兼容所有子类集合的场景
  • 大部分通用遍历、聚合计算的工具方法都会这么实现,避免为每种子类集合重复写相同逻辑。

内容的提问来源于stack exchange,提问作者JiA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 05:24:04