Java泛型疑问:推断类型不符合相等约束,sort方法调用报错差异
理解Java泛型中Comparable边界的问题:为什么
<T extends Comparable<T>>会导致子类列表排序报错? 嘿,我来帮你把这个问题掰扯明白——这其实是Java泛型里关于Comparable接口边界设计的经典细节,很多刚接触泛型的同学都会卡在这里!
首先先把你没写完的代码补全(应该是这样的场景对吧?):
import java.util.Collections; import java.util.List; class Person implements Comparable<Person> { @Override public int compareTo(Person o) { return 0; } } class Student extends Person {} public class GenericSort { // 你一开始用的sort方法,边界是<T extends Comparable<T>> public static <T extends Comparable<T>> void sort(List<T> list) { Collections.sort(list); } public static void main(String[] args) { List<Person> personList = List.of(new Person()); List<Student> studentList = List.of(new Student()); sort(personList); // 你说的第41行,正常编译 sort(studentList); // 你说的第38行,编译器报错 } }
先搞懂为什么第38行报错,第41行却正常
咱们先看Person的定义:它实现了Comparable<Person>,所以当调用sort(personList)时,泛型参数T被推断为Person,此时检查Person extends Comparable<Person>——完全符合边界要求,编译器自然没意见。
但轮到Student的时候就不一样了:Student继承了Person,但它并没有自己实现Comparable<Student>,而是继承了Person的Comparable<Person>实现。这时候泛型参数T被推断为Student,编译器会检查Student extends Comparable<Student>吗?显然不满足!因为Student对应的Comparable接口是针对Person的,不是针对自己的。
为什么改成<T extends Comparable<? super T>>就都正常了?
说白了,这个边界是在告诉编译器:只要T能和它自己或者它的父类实例比较就行,而不是严格要求必须和T自己的实例比较。
咱们用Student来验证:
? super T在这里代表Student的父类(包括Person和Object)Comparable<? super Student>就包含了Comparable<Person>(因为Person是Student的父类)- 而
Student继承了Person的compareTo(Person)方法,完全可以处理Student实例(毕竟Student也是Person的一种),所以Student满足Student extends Comparable<? super Student>的边界要求,自然就能编译通过了。
这个边界其实是Java标准库中Collections.sort方法的标准写法,就是为了支持这种子类继承父类比较逻辑的场景,避免出现你遇到的这种编译错误。
内容的提问来源于stack exchange,提问作者Ravi
相关产品推荐
相关产品推荐

