一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Java中 System.arraycopy 出现 ArrayStoreException 报错如何排查

时间:2026-07-20 18:04:48 编辑:袖梨 来源:一聚教程网

ArrayStoreException 表明尝试将不兼容类型的元素复制到引用类型数组中,System.arraycopy 在运行时严格检查类型兼容性;常见于源数组实际元素类型无法赋值给目标数组组件类型,如将 Integer[] 复制到 String[],或误用 list.toArray() 返回的 Object[] 直接复制到 String[];该异常仅发生在引用类型数组间,基本类型数组复制不会触发。

出现 ArrayStoreException 说明你正在尝试把不兼容类型的元素复制进目标数组,而 System.arraycopy 在运行时做了类型检查并拒绝了该操作。

确认源数组和目标数组的组件类型是否兼容

这是最常见原因:目标数组是某个类或接口的数组(比如 String[]Number[]),但源数组里存在无法赋值给该类型的对象(比如把 IntegerString[] 里复制)。Java 数组是协变的,但类型检查在复制时严格进行。

  • 检查源数组声明类型(如 Object[] src = new Integer[3];)和目标数组声明类型(如 String[] dst = new String[3];
  • 即使源数组实际元素都是 String,若其编译时类型是 Object[],而目标为 String[],复制仍可能失败——关键看运行时目标数组的组件类型能否接受源元素的实际类型
  • 一个典型例子:Object[] src = {new Integer(1)}; String[] dst = new String[1]; System.arraycopy(src, 0, dst, 0, 1); → 直接抛出 ArrayStoreException

注意泛型擦除与 Object[] 的陷阱

使用集合转数组时容易踩坑,例如 list.toArray() 返回的是 Object[],如果直接复制到具体类型数组中,JVM 会在运行时校验每个元素是否可存入目标类型。

  • 错误写法:String[] arr = new String[list.size()]; System.arraycopy(list.toArray(), 0, arr, 0, list.size());
  • 正确做法:用带参数的 toArray(T[]) 方法,如 String[] arr = list.toArray(new String[0]);,它会返回真正 String[] 类型的数组
  • 若必须用 arraycopy,确保源数组的运行时类型与目标一致,例如先用 Arrays.copyOf 或显式转型(需保证安全)

检查是否误用了基本类型数组与引用类型数组

ArrayStoreException 只发生在引用类型数组之间。如果你看到这个异常,说明至少有一个参数是引用类型数组(如 String[]Integer[]),而不是 int[]double[] 等基本类型数组。

立即学习“Java免费学习笔记(深入)”;

  • 基本类型数组之间复制不会抛 ArrayStoreException(但可能有 ArrayIndexOutOfBoundsException 或类型不匹配导致静默截断)
  • 混合使用时要特别小心:比如把 Integer[] 复制到 Number[] 是合法的(因为 IntegerNumber 子类),但复制到 String[] 就非法
  • 可通过 src.getClass().getComponentType()dst.getClass().getComponentType() 打印对比确认

调试建议:快速定位问题元素

异常堆栈通常不指出是第几个元素出错,但你可以手动模拟校验逻辑缩小范围。

  • 在调用 arraycopy 前加一层循环检查:for (int i = 0; i
  • 或者用 IDE 调试模式,停在异常前观察 src[i] 的实际类型和 dst 的组件类型
  • 日志中打印 src.getClass().getName()dst.getClass().getName(),比如 [Ljava.lang.String; 表示 String[][Ljava.lang.Object; 表示 Object[]

热门栏目