两个Java泛型binarySearch方法是否支持接收相同的数据类型?
结论
两个方法支持的传入参数范围完全不一致,JDK 自带的第一个签名支持的场景更广,你修改后的第二个签名存在较多使用限制。
核心区别
你修改后的签名要求「列表元素类型和 key 的类型完全相同,且该类型必须实现了Comparable<? super T>接口」,而 JDK 的原生签名将列表元素类型和 key 类型解耦,只要求列表元素实现的Comparable接口支持和 key 类型做比较即可,不需要二者类型一致。
具体反例
我们可以用继承场景直观感受到差异:
// 父类实现 Comparable 接口,按年龄排序 class Person implements Comparable<Person> { int age; public Person(int age) {this.age = age;} @Override public int compareTo(Person o) { return Integer.compare(this.age, o.age); } } // 子类继承Person,不需要重复实现Comparable class Student extends Person { public Student(int age) {super(age);} }
现在有如下调用需求:
List<Student> studentList = List.of(new Student(16), new Student(18), new Student(20)); Person target = new Person(18); // 用父类类型作为查找key
- 用JDK原生签名可以正常编译运行,返回下标1
- 用你修改后的签名会直接编译报错:
- 如果把泛型
T推断为Person,则List<Student>不符合List<Person>的参数要求 - 如果把泛型
T推断为Student,则target的Person类型不符合T的参数要求
- 如果把泛型
设计思路
JDK 签名中使用List<? extends Comparable<? super T>>的通配符组合,就是为了兼容「列表存子类实例、用父类规则比较、key 用父类类型」的常见场景,最大化方法的适用范围。
内容的提问来源于stack exchange,提问作者JS starter
相关产品推荐
相关产品推荐

