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

Java数组sort方法类型边界:Comparator<? super T>与<T>的差异示例

示例:Arrays.sort 两种泛型声明的差异

先明确两个方法声明:

可正常运行的声明:

public static <T> void sort(T[] a, Comparator<? super T> c)

无法适配场景的声明:

public static <T> void sort(T[] a, Comparator<T> c)

具体场景代码

首先定义类结构:

class Animal {
    private String name;
    public Animal(String name) { this.name = name; }
    public String getName() { return name; }
}

class Dog extends Animal {
    public Dog(String name) { super(name); }
}

然后创建一个针对Animal的比较器:

// 用于比较Animal及其子类的比较器
Comparator<Animal> animalNameComparator = (a1, a2) -> a1.getName().compareTo(a2.getName());

两种声明的调用差异

  1. 使用带<? super T>的声明:
Dog[] dogs = {new Dog("Buddy"), new Dog("Max"), new Dog("Charlie")};
// 完全可行:Comparator<Animal>是Comparator<? super Dog>的子类型
sort(dogs, animalNameComparator);

这里T被推断为Dog,Comparator<? super Dog>可以接受Comparator<Animal>(因为Animal是Dog的父类),所以编译通过,运行正常。

  1. 使用仅Comparator<T>的声明:
Dog[] dogs = {new Dog("Buddy"), new Dog("Max"), new Dog("Charlie")};
// 编译报错:Comparator<Animal>无法转换为Comparator<Dog>
sort(dogs, animalNameComparator);

此时T推断为Dog,方法要求传入Comparator<Dog>,但我们只有Comparator<Animal>,而泛型是不可协变的——Comparator<Animal>不是Comparator<Dog>的子类,所以编译失败。

原理说明

这是泛型中PECS原则的典型应用:当我们需要消费(接收)类型T的对象时,应该使用? super T(Producer Extends, Consumer Super)。比较器在比较T类型对象时,只需要能接收T或其父类的对象即可,所以用? super T可以让比较器的适用范围更广,支持父类比较器操作子类数组的场景,而仅用Comparator<T>会限制只能使用同类型的比较器,灵活性大打折扣。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:15:36