java - Java泛型方法使用compareTo方法问题从集合中查找'max'对象
问题描述
让我们假设我们有
class A implements Comparable<A>
和
class B extends A
现在,我想要一个通用方法,使用compareTo
方法从集合中找到最大的对象。
如果我这样声明这个方法:
public static <T extends Comparable<T>> T max(List<T> list)
它不适用于参数List<B> list
,因为B
不Comparable
使用 type参数化B
。为了使这种方法起作用,我改变似乎很自然
Comparable<T>
到
Comparable<? super T>
因此,更改后的方法将如下所示:
public static <T extends Comparable<? super T>> T max(List<T> list)
现在传递参数List<B> list
工作正常并且没有错误。美好的。但是当我将方法签名更改为
public static <T extends Comparable<T>> T max(List<? extends T> list)
它也适用于争论List<B> list
!我的问题是为什么。有人可以向我解释一下吗?谢谢 :)
解决方案
List<? extends T>
意思是“一个列表。我们不知道列表是什么,但无论它是什么,我们都知道它扩展了 T 或者是 T 本身。”
这样做的一个效果是,当我们从 List 中获取一个元素时,编译器会知道它是 T 类型。该项目的实际运行时类可能是 T 的子类型,多态性总是如此,但没有人关心那个。我们知道它可以存储在变量类型 T 中。
另一个影响是我们不能在 List 中放入任何元素,因为我们不知道 List 是什么。因此,无论我们尝试放入什么,我们都不知道它是否是可接受的类型,因此我们不能。但是当找到最大值时,这并不重要:无论如何我们都不会添加任何东西。
因此,如果需要,List<B>
也可以将 a 视为 a List<? extends A>
(突然决定我们不知道不关心 List 是什么,但无论它扩展 A 是什么。)这很有帮助,因为它允许匹配方法签名,以 T 为 A。
推荐阅读
- spring-cloud - 如何在 SpringGateway ServerWebExchange 中设置属性
- spring - Spring boot MissingServletRequestParameterException 异常无法读取请求参数
- flutter - 如果flutter中的firestore快照中没有可用数据,如何显示“无可用数据”消息?
- angular - 如何编写使用mergeMap()的角度服务的单元测试?
- google-apps-script - 谷歌脚本使用 replaceText 函数
- c# - MVC 5 如何验证可空整数
- reactjs - i18next-react - 如何在同一个应用程序中拥有 2 个 i18next 实例
- c# - WPF MyTextBox.Focus() 返回 true 但似乎窗口实际上具有焦点
- android - 没有系统提供对话框的 BiometricPrompt
- julia - 对 Julia、Turing.jl 和 Distributions.jl 中的概率编程语言感到困惑