核心目的是支持继承体系下的安全比较,而非仅限T自身实现Comparable<T>;例如LocalDate未实现Comparable<LocalDate>,但实现了Comparable<ChronoLocalDate>,因LocalDate是其子类,故? super T可容纳该关系,确保compareTo调用合法且兼容JDK类型。

这个泛型边界 T extends Comparable<? super T> 的核心目的,是让类型 T 能安全、灵活地参与比较,尤其在排序或二分查找等通用算法中。
为什么不是简单的 T extends Comparable<T>?
写成 T extends Comparable<T> 看似直观,但会限制继承体系中的合理比较。比如:
-
LocalDate实现的是ChronoLocalDate,而后者才实现Comparable<ChronoLocalDate>; -
LocalDate本身没直接实现Comparable<LocalDate>,所以无法满足T extends Comparable<T>(此时T = LocalDate); - 但
LocalDate确实能和自身比较(date1.compareTo(date2)成立),因为它实现了Comparable<ChronoLocalDate>,而LocalDate是ChronoLocalDate的子类 —— 这正好被? super T捕获。
? super T 的实际作用
它表示:只要 T 能被某个它的父类型(包括自己)所定义的 Comparable 所接受,就满足约束。换句话说:
-
T不必自己直接实现Comparable<T>; - 只要存在某个上界类型
U(U是T的父类或接口),使得T实现了Comparable<U>,就合法; - 这样就能调用
t1.compareTo(t2):因为t2是T类型,而T属于U,所以compareTo(U)可以接收它。
典型使用场景
这个边界常见于工具方法或集合算法的泛型声明中,例如:
立即学习“Java免费学习笔记(深入)”;
-
Collections.sort(List<T> list)内部要求元素可比,其签名正是基于T extends Comparable<? super T>; - 自定义泛型二分查找方法:
<T extends Comparable<? super T>> int binarySearch(T[] a, T key); - 它确保传入的数组元素既能互相比较,又兼容继承结构(如
ArrayList<LocalDate>可直接排序)。
错误写法的风险
如果误写为 T extends Comparable<T>:
- 会导致
LocalDate、BigDecimal(实现Comparable<Number>)、或自定义继承链中的子类无法通过编译; - 看似“更严格”,实则破坏了多态性和 JDK 已有类型的兼容性;
- 违背了 PECS 原则(Producer Extends, Consumer Super)——这里
compareTo方法是“消费”参数,所以用super更合理。


















