system.arraycopy是jvm层面的内存块搬运指令,非语法糖或复制函数;需手动控制边界、预分配空间,参数错误即抛异常,支持局部复制、数组拼接、部分迁移,但不深拷贝对象且禁止跨类型存储。

System.arraycopy 不是语法糖,也不是“复制函数”,它是一条 JVM 层面的内存块搬运指令。局部复制和数组拼接都靠它完成,但必须手动控制边界、提前分配空间,参数错一个就立刻抛异常。
局部复制:本质是“指定区间搬运”
所谓截取,就是把源数组某一段内容,拷贝到另一个已存在的目标数组里。关键不在“取”,而在“往哪放、放多少、从哪开始读”。
- 目标数组必须提前 new 好,长度至少为要拷贝的元素个数;arraycopy 不负责分配内存
- 起始位置 srcPos 是下标,不是字节偏移量;比如想取索引 5 开始的 8 个元素,就写
srcPos = 5 - 必须满足
srcPos + length ≤ src.length,否则运行时直接抛ArrayIndexOutOfBoundsException - 若目标数组是源数组本身(即原地操作),JVM 会自动判断搬运方向,避免中间数据被覆盖
数组拼接:两步搬运,位置不能错
拼接不是一次调用能完成的事,而是两次独立的 arraycopy 操作,第二步的目标起始位置必须紧接第一步的结尾。
- 先算总长:
int[] result = new int[a.length + b.length] - 第一段:把 a 拷到 result 开头 ——
System.arraycopy(a, 0, result, 0, a.length) - 第二段:把 b 拷到 result 的 a.length 处 ——
System.arraycopy(b, 0, result, a.length, b.length) - 常见错误:第二段的
destPos写成 0 或 b.length,会导致覆盖或越界
部分迁移:抽取+插入,需分步腾空间
要把 source 中 [3,7) 这 4 个元素,插进 target 的索引 12 起的位置,不是简单一调就完事。
- 先校验:source 长度 ≥ 7,target 长度 ≥ 16(12 + 4)
- 如果 target 原来在 12 及之后还有有效数据,且你希望保留它们,就得先用 arraycopy 把这些数据整体右移腾出空位
- 再执行迁移:
System.arraycopy(source, 3, target, 12, 4) - 注意:这不会改变 source,也不扩容 target,一切空间管理由你负责
类型与安全:只认引用,不深拷贝
arraycopy 对基本类型是值拷贝,对对象数组只是复制引用——这点在二维数组或含可变对象的数组中尤其关键。
- 二维数组中,
System.arraycopy(grid[i], 0, grid[j], 0, len)拷的是 int 值,安全;但若元素是 Person 对象,拷过去的是同一份引用 - 若需真正隔离修改,后续必须手动深拷贝对象,arraycopy 本身不提供该能力
- 跨类型拷贝(如 Object[] → String[])可能通过编译,但运行时抛
ArrayStoreException











