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
相关产品推荐
相关产品推荐

