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

当Comparator不为null时,Arrays.sort(T[], Comparator)是否会抛出ClassCastException?

Arrays.sort(T[], Comparator<? super T>)的ClassCastException触发场景分析

问题背景

Java 20标准库java.util.Arrays的sort(T[] a, Comparator<? super T> c)方法Javadoc说明:该方法会根据指定Comparator对数组排序,要求所有元素可通过该Comparator相互比较(即c.compare(e1,e2)不会抛出ClassCastException),若元素无法比较则抛出该异常。

这里存在疑问:当传入的Comparator实例c不为null时,编译器的泛型类型系统是否已保证数组元素可通过c相互比较,不会触发ClassCastException?

类型擦除视角的分析

该方法经类型擦除后的签名为static void sort(Object[] a, Comparator c)。假设c的静态类型是Comparator<Number>,它的compare方法会将参数转换为Number类型,这个转换成功的前提是数组元素的运行时类型为Number或其子类,而这依赖于数组的运行时类型是Number[]或其子类。

从方法泛型签名来看,? super T的约束能保证数组静态类型符合要求(比如当? super T为Number时,T是Number或其子类)。如果数组运行时类型不符合要求,会在进入sort方法之前就抛出ClassCastException,而非方法内部抛出。

测试验证结果

编写测试案例验证后发现:

  • 仅当传入null作为Comparator时,sort方法本身才会抛出ClassCastException;
  • 其他看似抛出该异常的场景,实际都是进入sort方法前的数组类型转换异常;
  • 传入静态类型不符的数组会直接触发编译错误。

核心疑问

  1. 是否只有传入null作为Comparator时,Arrays.sort(T[], Comparator)才会抛出ClassCastException?
  2. 是否存在无需编译器unchecked警告且c不为null的场景,导致该方法抛出该异常?

测试代码

package org.example.basics.generics.arrays;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.Comparator;

class ArraysTest {

    private static final Comparator<Number> compareAsWholeNumber = new Comparator<Number>() {
        @Override
        public int compare(java.lang.Number o1, java.lang.Number o2) {
            return Long.compare(o1.longValue(), o2.longValue());
        }
    };

    @Test
    public void sortingIntsThrowsNoException() {
        Integer[] ints = new Integer[]{4, 2, 3};
        Assertions.assertDoesNotThrow(() -> {
            Arrays.sort(ints, compareAsWholeNumber);
        });

    }

    @Test
    public void sortingDoublesThrowsNoException() {
        Double[] doubles = new Double[]{4.0, 2.0, 3.0};
        Assertions.assertDoesNotThrow(() -> {
            Arrays.sort(doubles, compareAsWholeNumber);
        });
    }

    @Test
    public void sortingNumbersThrowsNoException() {
        Number[] numbers = new Number[]{4.0, 2, 3.0f};
        Assertions.assertDoesNotThrow(() -> {
            Arrays.sort(numbers, compareAsWholeNumber);
        });
    }

//    @Test
//    public void sortingObjectsIsCompileError() {
//        Object[] numbers = new Number[]{4.0, 2, 3.0f};
//        Arrays.sort(numbers, compareAsWholeNumber);
//    }

    @Test
    public void sortingDisguisedStringsThrowsClassCastException() {
        Throwable e = Assertions.assertThrows(ClassCastException.class, () -> {
            Arrays.sort((Number[]) new Object[]{"4.0", "2", "3.0f"}, compareAsWholeNumber);
        });
        e.printStackTrace();
    }

    @Test
    public void sortingDisguisedStringsThrowsClassCastExceptionAtArrayAssignment() {
        Assertions.assertThrows(ClassCastException.class, () -> {
            Number[] numbers = (Number[]) new Object[]{"4.0", "2", "3.0f"};
        });
    }
    @Test
    public void sortingNonComparableWithNullComparatorThrowsClassCastException() {
        Number[] numbers = new Number[]{4.0, 2, 3.0f};
        Throwable e = Assertions.assertThrows(ClassCastException.class, () -> {
            Arrays.sort(numbers, null);
        });
        e.printStackTrace();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 21:25:06