system.arraycopy不能直接深拷贝二维数组,因其仅复制引用而非对象内容;对int[][]需两层循环新建子数组并复制元素,对person[][]还需克隆每个对象,string[][]因不可变性表现安全但仍是浅拷贝。

System.arraycopy 本身不能直接完成二维数组的深层拷贝,它只复制内存块,不识别维度结构。要实现真正的深拷贝,必须手动分层处理:先新建外层数组容器,再为每一行单独分配新子数组,并用 arraycopy 复制数值。
为什么直接调用会失败
Java 中的 int[][] 实质是“一维引用数组”,每个元素(如 src[0])是一个指向独立 int[] 对象的引用。直接写:
System.arraycopy(src, 0, dst, 0, src.length);
只会把这组引用复制过去,dst[i] 和 src[i] 指向同一块内存。改 dst[0][0] 就等于改 src[0][0],这不是拷贝,是共享。
基本类型二维数组(如 int[][])的正确步骤
对元素为 int、double 等基本类型的二维数组,深拷贝需两层操作:
- 创建新的外层数组:int[][] dst = new int[src.length][];
- 遍历每一行,为 dst[i] 分配新子数组:dst[i] = new int[src[i].length];
- 用 arraycopy 复制该行所有数值:System.arraycopy(src[i], 0, dst[i], 0, src[i].length);
这样每行都是独立内存,修改 dst 不会影响 src。
对象类型二维数组(如 Person[][])需额外深克隆元素
如果子数组里存的是可变对象(比如 Person[]),仅复制子数组引用还不够。即使 dst[i] 是新数组,它的每个元素仍可能指向原 Person 实例。
必须在复制完子数组后,再逐个处理元素:
- 若 Person 实现了 Cloneable:dst[i][j] = (Person) src[i][j].clone();
- 或用构造方法重建:dst[i][j] = new Person(src[i][j].getName(), src[i][j].getAge());
- 避免直接用 arraycopy 处理对象数组——它只搬引用,不搬对象状态。
String[][] 是个例外,但不是真深拷贝
String 不可变,所以用 arraycopy 或 clone 复制 String[][] 通常不会引发数据污染。例如修改 dst[0][0] = "new",src[0][0] 不变,因为这是赋新引用,旧 String 未被修改。
但这仍是浅拷贝:dst[0] 和 src[0] 指向同一个 String[] 对象。若执行 dst[0] = new String[]{"x"},才真正切断引用;而 dst[0][0] = "y" 这类操作安全,靠的是 String 的不可变性,不是 arraycopy 的能力。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











