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

Java泛型中List<T>与List<? extends T>在示例中的差异是什么

代码正常运行的原因

你传入的参数是List<Vehicle>,Java泛型推断时会把T明确推导为Vehicle类型:

  • Vehicle本身实现了Comparable<Vehicle>,完全符合<T extends Comparable<? super T>>的约束(? super Vehicle可以匹配Vehicle自身)
  • List<Vehicle>允许存放Vehicle及其子类的实例,你往列表里加Car对象是Java多态的基础特性,本身就是合法的
  • 运行时调用compareTo方法时,实际执行的是Vehicle类的实现,比较逻辑完全正常,所以整个代码可以正常运行。

两种方法声明的差异

原声明:public static <T extends Comparable<? super T>> int findSmallestIndex(List<T> itemList)

要求传入的列表元素类型严格等于泛型参数T,类型推断时会直接把T绑定到列表的元素类型上。

修改后声明:public static <T extends Comparable<? super T>> int findSmallestIndex(List<? extends T> itemList)

允许传入的列表元素类型是T的任意子类,灵活性更高。

举个最直观的差异场景:如果你现在有一个List<Car>要传入方法:

  • 用原声明的话,T会被推断为Car,虽然Car也符合Comparable<? super Car>的约束(因为父类Vehicle实现了Comparable<Vehicle>),但如果你希望显式指定T为Vehicle做更通用的处理,调用findSmallestIndex<Vehicle>(carList)会直接报错,因为List<Car>无法赋值给List<Vehicle>
  • 用修改后的声明的话,List<Car>符合List<? extends Vehicle>的要求,显式指定T为Vehicle也可以正常调用。

要不要改成第二种写法?

非常建议改。根据Java泛型的PECS原则(Producer Extends, Consumer Super):你的方法只从列表中读取元素,列表是提供元素的「生产者」,使用? extends T的上限通配符可以在完全不影响功能的前提下,大幅提升API的适用范围,又不会引入任何副作用(因为? extends的列表本来就不允许写入任意元素,而你的方法本来就不会修改列表)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:42:01