System.arraycopy对多维数组仅做浅拷贝,只复制引用而非内容;若需深拷贝,须逐行新建数组并调用arraycopy复制元素,同时注意类型兼容性与重叠拷贝风险。

System.arraycopy 对多维数组只做第一层引用拷贝,不是你想的“整个表格一起复制”,它只搬引用,不搬内容。
多维数组拷贝本质是浅层引用搬运
比如 int[][] src = {{1,2}, {3,4}}; 用 arraycopy 复制到 dst 后,dst[0] 和 src[0] 指向同一个 int[] 对象。改 dst[0][0],src[0][0] 立刻变——这不是 bug,是设计如此。
- arraycopy 不识别“二维”语义,它眼里只有“一维对象数组”
- 源数组里存的是子数组的地址,它就把这些地址原样写进目标数组
- 对 String[][] 也一样:引用共享,但因 String 不可变,表面看没事
- 对 ArrayList
[][] 或自定义可变对象数组,共享引用就会引发双向修改
真要独立副本?必须手动逐行新建+复制
想让 dst 和 src 完全隔离,不能靠一次 arraycopy 解决,得两步走:
- 先为 dst 每一行分配新数组:dst[i] = new int[src[i].length]
- 再对每一行调用 arraycopy 搬数值:System.arraycopy(src[i], 0, dst[i], 0, src[i].length)
- 如果某行可能是 null,循环中需判空,否则抛 NullPointerException
- 不规则二维数组(各行长度不同)必须用 new int[src.length][] 声明 dst,不能写死列数
类型安全和运行时陷阱要盯紧
多维数组也是引用类型,赋值受 Java 协变规则约束:
立即学习“Java免费学习笔记(深入)”;
- String[][] 可以拷给 Object[][],因为 String 是 Object 子类
- 但 Number[][] 拷给 Integer[][] 会抛 ArrayStoreException——Number 不是 Integer 的子类
- 异常在运行时才爆发,已拷的部分不会回滚,结果不可逆
- 编译能过 ≠ 运行安全,务必确保组件类型兼容
同一数组内操作容易踩重叠覆盖坑
对一个二维数组自身做移位(比如滚动缓冲区),若 src == dest,arraycopy 虽会自动判断方向,但逻辑稍错就丢数据:
- 向左平移某行:arraycopy(row, 3, row, 0, 3) → JVM 正向执行,安全
- 向右平移某行:arraycopy(row, 0, row, 3, 3) → JVM 倒序执行,安全
- 但若区间部分重叠且 destPos 与 srcPos 关系混乱(如本该倒序却误设正向意图),结果不可预测
- 稳妥做法:重叠场景优先用临时数组中转,或显式循环控制读写顺序


















