system.arraycopy不支持多维数组深拷贝,仅复制引用;深拷贝需分层分配新数组并逐行调用arraycopy搬运数据,适用于任意维度且性能更优。

System.arraycopy 本身不支持多维数组的“一键深拷贝”,它只作用于一维内存块。要高效复制 int[][]、String[][] 等多维数组,必须理解其底层结构——Java 中的二维数组本质是“引用数组”,每一行都是独立对象。真正的复制需分层操作:先分配新容器,再逐行搬运数据。
为什么直接用 arraycopy 复制二维数组会出问题
对 int[][] src 调用 System.arraycopy(src, 0, dst, 0, src.length),只会复制外层数组中“指向子数组的引用”。结果是 dst[0] == src[0] 为 true,修改 dst[0][1] 会同步改掉 src[0][1]。这不是 bug,而是 arraycopy 的设计本意:它不做递归,只做内存级平移。
- 它把二维数组当成 Object[] 来处理,每个元素(即每行)都是一个引用
- 不会检查或复制引用所指向的内容,null 子数组也不会跳过,直接抛 NullPointerException
- 类型兼容性在运行时校验,比如把 Number[][] 拷到 Integer[][] 会触发 ArrayStoreException
手动实现 int[][] 的真正深拷贝
核心是两步:分配新行 + 用 arraycopy 搬数值。适用于规则或不规则二维数组(各行长度可不同)。
- 先创建目标外层数组:int[][] dest = new int[src.length][];
- 遍历每一行:for (int i = 0; i
- 为当前行分配新空间:dest[i] = new int[src[i].length];
- 调用 arraycopy 搬数据:System.arraycopy(src[i], 0, dest[i], 0, src[i].length);
- 若某行可能为 null,加判空:if (src[i] != null) { ... }
扩展到三维及更高维数组
逻辑一致,只是嵌套加深。以 int[][][] 为例:
- 分配外层:int[][][] dest = new int[src.length][][];
- 对每个 src[i](它是 int[][] 类型),执行完整的二维深拷贝流程
- 即:new int[src[i].length][], 再逐行 new + arraycopy
- 无需递归方法,三层 for 循环即可清晰控制每一维的内存分配与数据搬运
性能优势与关键提醒
相比 Arrays.deepCopy 或双层 for 循环,arraycopy 方案在大数据量下优势明显:底层调用 native 内存指令,避免装箱拆箱和重复边界检查。
- 基本类型数组(如 int[][])拷贝总长度 ≥ 256 时,提速显著
- 目标数组必须提前分配好,不能依赖 arraycopy 自动扩容
- 所有参数必须合法:src/dest 非 null、索引不越界、length 不负、类型兼容
- 对象数组(如 String[][])用 arraycopy 是安全的(因 String 不可变),但 ArrayList
[][] 就需额外克隆内部对象
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











