System.arraycopy是JVM底层内存搬运指令,性能高但参数严格:五个参数顺序固定、均需校验,同数组移位自动选择正/倒序避免覆盖,仅在数据量大、目标数组预分配、类型干净时稳定提速。

System.arraycopy 不是普通复制方法,而是 JVM 底层内存搬运指令。它快,是因为跳过 Java 层循环和逐元素检查;它严,是因为参数错一个就立刻抛异常——不静默、不宽容。
五个参数必须对齐,一个都不能错
调用格式固定为:System.arraycopy(src, srcPos, dest, destPos, length),顺序不可变:
- src:源数组,不能为 null,否则抛 NullPointerException
- srcPos:读取起始下标,必须 ≥ 0 且 ≤ src.length;若 srcPos + length > src.length,直接 ArrayIndexOutOfBoundsException
- dest:目标数组,必须已 new 完成,类型需兼容(如 String[] 可拷入 Object[],但 int[] 不能拷入 long[])
- destPos:写入起始下标,必须 ≥ 0,且 destPos + length ≤ dest.length
- length:拷贝元素个数,可为 0(合法空操作,用于快速边界预检),但不能为负
同数组原地移位:方向由参数自动决定
当 src 和 dest 是同一个数组时,JVM 根据 srcPos 与 destPos 的大小关系,自动选择正向或倒序搬运,避免覆盖:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 左移(destPos < srcPos):如把 arr[4..8] 前移到 arr[2..6],写 System.arraycopy(arr, 4, arr, 2, 5),JVM 正向执行,安全
- 右移(destPos > srcPos):如把 arr[2..6] 后移到 arr[5..9],写 System.arraycopy(arr, 2, arr, 5, 5),JVM 倒序搬运,先处理高位再覆盖低位
- 禁止无效搬运:srcPos == destPos 且 length > 0 虽合法,但纯属浪费校验开销
真正提速的三个硬条件
arraycopy 不是“用了就快”,它的性能优势只在满足以下条件时才稳定释放:
立即学习“Java免费学习笔记(深入)”;
- 数据量够大:基本类型(int[]、byte[])建议 length ≥ 256;≤16 时 for 循环反而更快(JNI 开销盖过收益)
- 目标数组已预分配:Arrays.copyOf 会 new 新数组,clone() 无法指定范围,而 arraycopy 是唯一零分配搬运方式
- 类型干净 + 参数稳定:避免运行时变量传参;length 用常量更易被 JIT 内联;跨类型拷贝(如 int[] → Integer[])直接 ArrayStoreException
高频实用场景写法
不是所有拷贝都适合 arraycopy,但这些典型模式值得固化为工具逻辑:
- 截取子段:先 new 目标数组,再 System.arraycopy(src, from, dest, 0, to - from)
-
拼接数组:分两步写入,如拼 a 和 b 到 result:
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length) - 缓冲区复用:预分配大 byte[] pool,每次用 arraycopy 写入指定 offset,避免频繁 GC
- 环形缓冲前移:如 RingBuffer 中 unreadCount 数据从 readPos 开始搬至头部,System.arraycopy(buf, readPos, buf, 0, unreadCount)


















