你遇到了 ArrayStoreException 异常?这是 Java 在运行时执行的一次类型安全检查,只是它直接拒绝了你的操作。简单来说,当 System.arraycopy 执行复制时,发现源数组中的某个元素类型与目标数组的组件类型不兼容,因此果断抛出了这个异常。

问题根源在哪里?核心其实只有一句话:目标数组期望接收的元素类型,与源数组里实际存储的元素类型不匹配。下面我们逐步拆解,看看如何一步步定位并解决这个问题。
确认源数组和目标数组的组件类型是否兼容
这是最常见的原因。目标数组声明为 String[],但源数组里却包含了一个 Integer 对象——尽管 Java 数组是协变的,但 System.arraycopy 在运行时会对每个元素逐一检查,一旦发现类型不匹配,就会直接抛出异常。
- 检查源数组的声明类型和目标数组的声明类型。例如源数组声明为
Object[] src = new Integer[3];,目标数组是String[] dst = new String[3];,两者一碰就会触发异常。 - 即使源数组里实际存储的都是
String对象,但如果它的编译时类型是Object[],而目标数组是String[],复制时仍可能失败。关键在于运行时目标数组的组件类型能否接受源元素的实际类型——JVM 不会因为“看起来都是 String”就网开一面。 - 一个典型例子:
Object[] src = {new Integer(1)}; String[] dst = new String[1]; System.arraycopy(src, 0, dst, 0, 1);→ 直接抛出ArrayStoreException,因为Integer无法放入String[]。
注意泛型擦除与 Object[] 的陷阱
从集合转数组时,这个坑尤其容易踩。例如 list.toArray() 返回的是 Object[],你直接把它往 String[] 里复制,JVM 在运行时当然会较真——它会逐个检查每个元素是否为 String。
- 错误写法:
String[] arr = new String[list.size()]; System.arraycopy(list.toArray(), 0, arr, 0, list.size());这行代码大概率会失败,因为list.toArray()返回的数组运行时类型是Object[],而不是String[]。 - 正确做法:使用带参数的
toArray(T[])方法,例如String[] arr = list.toArray(new String[0]);,它返回的是真正的String[]类型数组,复制时自然安全。 - 如果非要用
arraycopy,就得确保源数组的运行时类型与目标数组一致。可以先通过Arrays.copyOf进行一次安全转型,或者显式进行类型转换(前提是你能保证所有元素都是目标类型)。
检查是否误用了基本类型数组与引用类型数组
这里有一个关键点:ArrayStoreException 只发生在引用类型数组之间。如果你看到这个异常,那么至少有一个参数是引用类型数组(例如 String[]、Integer[]),绝对不会是 int[]、double[] 这类基本类型数组。
- 基本类型数组之间复制时,不会抛出
ArrayStoreException(但可能因数组长度不够而抛出ArrayIndexOutOfBoundsException,或者类型不匹配导致静默截断)。 - 混合使用时尤其要小心:把
Integer[]复制到Number[]是合法的,因为Integer是Number的子类;但复制到String[]就非法了。 - 可以用
src.getClass().getComponentType()和dst.getClass().getComponentType()打印出实际组件类型,对比一下就能快速定位问题。
调试建议:快速定位问题元素
异常堆栈通常不会告诉你具体是第几个元素出了问题,不过我们可以手动模拟校验逻辑,快速缩小范围。
- 在调用
arraycopy之前,加一层循环逐个检查:for (int i = 0; i < length; i++) { if (!dst.getClass().getComponentType().isInstance(src[i])) { ... } },这样就能精确定位到出问题的元素。 - 或者用 IDE 的调试模式,在异常抛出前暂停,观察
src[i]的实际类型以及dst的组件类型。 - 日志中打印
src.getClass().getName()和dst.getClass().getName(),例如[Lja va.lang.String;表示String[],[Lja va.lang.Object;表示Object[],一目了然。
