system.arraycopy对多维数组仅做一层浅拷贝,即只复制外层数组引用,不递归复制内层数组内容;例如int[][] src经复制后,dst[0]与src[0]指向同一内存,修改dst0会同步影响src0。

多维数组用arraycopy,本质是“一层浅拷贝”
System.arraycopy对多维数组不做递归处理。比如int[][] src,它只复制外层数组的引用,不碰内部每一行的内容。也就是说,执行System.arraycopy(src, 0, dst, 0, src.length)后,dst[0] == src[0]为true——它们指向同一块内存。改dst[0][1],src[0][1]立刻跟着变。
二维基本类型数组:需手动分配每行再搬运
想真正独立拷贝int[][]、double[][]这类二维数组,必须两步走:先为每行新建子数组,再用arraycopy把数值搬过去。JVM不会替你做这层结构初始化。
- 目标数组
dst必须提前声明为new int[src.length][],不能是new int[src.length][src[0].length](那会固定列数,不适用于不规则二维数组) - 逐行循环:
for (int i = 0; i - 如果某行是null,记得判空,否则arraycopy会抛NullPointerException
二维对象数组:引用拷贝+对象克隆缺一不可
String[][]、MyBean[][]这类数组,arraycopy只复制引用,而对象本身是否可变,决定了污染风险大小。
- String[][]安全:因String不可变,共享引用无副作用
- ArrayList
[][]或自定义可变对象数组危险:arraycopy后, dst[i]和src[i]指向同一个ArrayList实例,add/remove操作会双向影响 - 真正深拷贝要分层处理:先用arraycopy复制外层数组引用,再遍历每行,对每个可变对象调用clone()、构造新实例或序列化反序列化
别踩这些原地拷贝的覆盖坑
在同一个二维数组上做移位重排(如滚动日志缓冲区),容易因方向错误导致数据被提前覆盖。
- 向右平移某一行:例如把
row[0..2]搬到row[3..5],因destPos > srcPos,JVM自动倒序执行,安全 - 向左平移某一行:例如把
row[3..5]搬到row[0..2],因destPos - 但若源区间和目标区间部分重叠且方向判断失误(如误用正向逻辑处理高位覆盖),结果不可预测——这不是bug,是内存级搬运的必然行为











