arrays.sort(t[] a, comparator

Arrays.sort 的泛型重载版本(Arrays.sort(T[] a, Comparator super T> c))本身不依赖运行时类型信息,但编译器能通过泛型约束在编译期拦截不安全操作——关键在于让 T 与 Comparator 的参数类型逻辑自洽。
明确泛型参数 T 的实际类型
泛型数组必须是引用类型(如 String[]、Person[]),不能是基本类型(int[] 不适用此泛型签名)。T 由数组声明类型决定,不是靠推断:
-
String[] strs = {...}; Arrays.sort(strs, String::compareTo);→ T 是String -
Number[] nums = {1, 2.5, BigDecimal.ONE}; Arrays.sort(nums, Comparator.comparing(Number::doubleValue));→ T 是Number,比较器接受Number或其父类(如Object) - 若写成
Arrays.sort(strs, (s1, s2) -> s1.length() - s2.length()),Lambda 类型自动匹配为Comparator<string></string>,仍满足? super String
避免 ClassCastException 的两个前提
即使编译通过,运行时仍可能抛出 ClassCastException,常见于以下情况:
- 数组元素实际类型不统一:例如声明
Object[] arr = {"a", 123};,再用String::compareTo排序 → 运行时对Integer调用String.compareTo()失败 - Comparator 实现中强制转型:如
(a, b) -> ((String)a).compareTo((String)b),当 a 或 b 是其他类型时直接崩 - 正确做法是确保数组内所有元素都可被该比较器安全处理,或使用
instanceof+ 分支逻辑(但会削弱类型安全意图)
null 值必须显式处理
泛型本身不解决 null 安全;Comparator 若未防御 null,就会触发 NullPointerException:
- 推荐用
Comparator.nullsFirst(Comparator.naturalOrder())或Comparator.nullsLast(String::compareTo) - 若字段提取可能为 null(如
User::getName),应嵌套包装:Comparator.comparing(User::getName, Comparator.nullsLast(String::compareTo)) - 避免在 Lambda 中直接调用
obj.field.method(),先判空或用Objects.toString(obj.field)等兜底
对比 Comparable 和 Comparator 场景
当对象自身实现 Comparable,用无参 Arrays.sort(arr) 更简洁且类型更稳;需多规则或临时逻辑时才用泛型 Comparator 版本:
-
Person[] ps = ...; Arrays.sort(ps);→ 要求Person implements Comparable<person></person>,编译器强制检查 -
Arrays.sort(ps, Comparator.comparing(p -> p.age));→ 编译器只校验p.age的类型是否支持自然序,不保证p非 null - 二者都要求数组元素类型一致,否则泛型擦除后运行时无法识别,错误延后到比较阶段











