system.arraycopy本身不直接截取数组,而是通过创建新数组并调用arraycopy(src, from, result, 0, len)实现高效分段截取;需严格校验参数、计算长度len=to−from,并确保类型一致与边界合法。

System.arraycopy 本身不直接“截断”数组,而是把一段数据从源位置高效搬进目标容器。真正实现截取,靠的是配合新数组创建与精准参数控制——它不是语法糖,是内存级搬运指令。
截取本质:先算长度,再配目标数组
截取区间 [from, to)(左闭右开)时,核心动作只有三步:
- 校验 from ≥ 0、to ≤ 源数组长度、from ≤ to,否则提前抛异常
- 计算真实长度:int len = to - from
- 创建目标数组:int[] result = new int[len](类型需与源一致)
- 执行搬运:System.arraycopy(src, from, result, 0, len)
例如 subArray(new int[]{1,2,3,4,5}, 1, 4) 返回 {2,3,4},全程无额外对象、无装箱、无 GC 压力。
高频截取场景:复用缓冲区降开销
当同一数组需反复截取不同片段(如日志分块、协议解析),每次都 new 小数组会加剧 GC。更优做法是:
- 预分配一个足够大的缓冲数组,如 byte[] buffer = new byte[8192]
- 每次调用 System.arraycopy(src, offset, buffer, 0, actualLen)
- 最后仅用 Arrays.copyOf(buffer, actualLen) 裁剪出结果
- 若后续只读,甚至可跳过裁剪,仅维护有效长度变量
边界安全:五个参数必须同时守规矩
arraycopy 不做宽容处理,任一违规立即崩溃:
- src 不能为 null,否则抛 NullPointerException
- srcPos 必须 ≥ 0 且 ≤ src.length
- dest 必须已初始化,且类型兼容(int[] 不能往 long[] 拷)
- destPos ≥ 0,且 destPos + length ≤ dest.length
- length ≥ 0,且 srcPos + length ≤ src.length
建议在封装工具方法时统一前置校验,尤其 when from/to 来自外部输入。
别和 Arrays.copyOfRange 混用场景
二者定位不同:
- Arrays.copyOfRange 是开箱即用的语义化方案:自动建数组、自动校验、适合日常业务逻辑
- System.arraycopy 是性能敏感场景的底层武器:可控、可复用、可拼接、可原地移位,但需手动管理目标数组
不需要追求“一定用 arraycopy”,该简洁时用 copyOfRange,该压测优化时才切入 arraycopy。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











