System.arraycopy不能安全拷贝多维数组,因其仅复制外层引用而非子数组内容;需分层处理:先为每行分配新空间,再用arraycopy逐行复制元素。

System.arraycopy 不能直接安全拷贝多维数组,它只复制外层数组的引用,不复制子数组内容。想真正隔离数据,必须分层处理——先分配新容器,再逐行复制元素。
为什么直接用 arraycopy 是不安全的
Java 的多维数组本质是“数组的数组”。比如 int[][] 实际是一个一维引用数组,每个元素指向一个 int[]。System.arraycopy 只能按内存块搬运引用,不会深入子数组内部。
- 执行
System.arraycopy(src, 0, dst, 0, src.length)后,dst[0] == src[0]为 true - 修改
dst[0][1]会同步改变src[0][1] - 这种共享引用在多线程或后续修改场景中极易引发数据污染
安全深拷贝二维数组(int[][] / double[][])
需两步:分配每行新空间 + 用 arraycopy 搬数值。关键点是目标子数组必须提前 new 出来。
- 声明目标数组:
int[][] dst = new int[src.length][];(不能写成new int[src.length][src[0].length],否则不支持不规则结构) - 遍历每一行:
for (int i = 0; i < src.length; i++) - 对非 null 行单独处理:
if (src[i] != null) { dst[i] = new int[src[i].length]; System.arraycopy(src[i], 0, dst[i], 0, src[i].length); }
对象数组(String[][] / Person[][])要额外注意
arraycopy 仍只复制引用,是否安全取决于元素类型是否可变:
立即学习“Java免费学习笔记(深入)”;
-
String[][] 安全:String 不可变,共享引用无副作用;但若后续执行
dst[i] = new String(...)是重新赋值,不影响原数组 -
ArrayList[][] 或自定义对象数组危险:
dst[i][j].add(...)会同时改 src 对应对象;必须对每个可变对象调用 clone()、构造新实例或序列化 - 安全做法:先 arraycopy 外层,再循环对每个非 null 元素做深克隆
并发环境下的额外防护
多线程读写同一多维数组时,仅靠 arraycopy 不够,还需控制访问权限:
- 避免让多个线程共用同一个 dst 数组;建议每次拷贝都新建目标数组
- 若源数组可能被其他线程修改,应在 synchronized 块内完成整个拷贝流程
- 更推荐方案:用
Arrays.copyOf()或original.clone()获取独立副本,它们封装了完整拷贝逻辑,调用即得隔离数据


















