system.arraycopy(src, 0, dest, 0, len) 是语义明确、性能极致的基础操作,实现整数组全量平移,要求len≤src.length且≤dest.length、类型兼容、非null,否则抛异常;它比arrays.copyof更底层,直接映射至memmove或simd指令,零解释开销。

System.arraycopy(src, 0, dest, 0, len) 是最常见、最直观的调用形式,但它并非语法糖或封装特例——它是一个语义明确、性能极致、边界严格的基础操作。理解它,是掌握整个 arraycopy 机制的起点。
这种写法的本质是“整数组全量平移”
它不隐含扩容、不触发类型转换、不自动分配内存,只做一件事:把 src[0] 到 src[len-1] 连续 len 个元素,按地址顺序原样搬到 dest[0] 到 dest[len-1]。
前提是:
-
len ≤ src.length且len ≤ dest.length -
src和dest类型兼容(如都是int[],或Object[]→String[]且所有元素确实是String) -
src和dest都不能为null
一旦任一条件不满足,立刻抛异常,不会静默截断,也不会默认补零。
它比 Arrays.copyOf 更底层、更可控
Arrays.copyOf(src, newLength) 内部其实就调用了 arraycopy,但多了一步:先 new 出目标数组。
而 arraycopy(src, 0, dest, 0, len) 要求你自己准备好 dest,好处是:
- 可复用已有数组(避免频繁分配/GC)
- 可精确控制目标位置(比如写入大缓冲区的某一段)
- 可与其他段拼接配合(如网络包组装、音视频帧拼接)
例如:
byte[] header = {1, 2, 3};
byte[] payload = {4, 5, 6, 7, 8};
byte[] packet = new byte[8];
System.arraycopy(header, 0, packet, 0, 3); // 前3字节填header
System.arraycopy(payload, 0, packet, 3, 5); // 后5字节填payload
它在 JVM 层直接映射到 memmove 或 SIMD 指令
当 src 和 dest 类型相同、连续、无重叠(即 src != dest 或 src == dest 但区间不重叠),HotSpot 会走最优路径:
- 基本类型数组 → 调用
memcpy或向量化内存拷贝(AVX/SSE) - 对象数组 → 检查元素类型后,批量复制引用(不触发
finalize、不走putfield字节码)
这正是它比 for 循环快数倍的核心原因:一次校验 + 一次底层搬运,零解释开销。
常见误用与规避方式
❌
dest长度不足:new int[4]; arraycopy(src, 0, dest, 0, 5)→ 直接ArrayIndexOutOfBoundsException
✅ 提前校验:if (len > dest.length) throw ...或用Math.min(len, dest.length)截断(但需自行处理逻辑)❌ 把
len当成目标数组长度:arraycopy(src, 0, new int[10], 0, src.length)—— 若src.length > 10仍会越界
✅ 明确区分:len是拷贝数量,不是目标容量❌ 混淆对象数组的“浅拷贝”语义:
String[]拷贝后,dest[i]和src[i]指向同一字符串实例
✅ 这是设计使然,非 bug;如需深拷贝,需额外逻辑
不复杂但容易忽略。











