system.arraycopy是jvm优化的高效数组拷贝方法,需正确设置非null源目标数组、合法索引及拷贝长度;引用类型仅浅拷贝,基本类型完全独立;null检查、扩容、转换等场景应选用其他方案。

Java 中数组拷贝看似简单,但用错方法会拖慢性能、浪费内存。System.arraycopy 是 JVM 优化过的本地方法,比 for 循环或 Arrays.copyOf 更快更省资源,关键在参数用对。
明确 source 和 dest 的起始位置
System.arraycopy 要求源数组和目标数组都非 null,且下标范围必须合法。常见错误是把 srcPos 或 destPos 设成负数,或超出数组长度,直接抛 ArrayIndexOutOfBoundsException。
- srcPos:从源数组第几个索引开始复制(从 0 开始)
- destPos:复制到目标数组的第几个索引位置
- 比如要把 arr1[2]~arr1[6] 拷贝到 arr2[0] 开始,就写 System.arraycopy(arr1, 2, arr2, 0, 5)
length 参数不是目标数组长度,而是要拷贝的元素个数
很多人误以为第三个参数是目标数组容量,其实它是“拷多少个”。这个值必须 ≥ 0,且满足:srcPos + length ≤ src.length 且 destPos + length ≤ dest.length,否则运行时报错。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 若只想拷贝前 3 个元素:length = 3
- 若想跳过头两个再拷 4 个:srcPos = 2,length = 4
- 目标数组如果已部分填充,destPos 可设为当前偏移量,实现追加式拷贝
引用类型数组注意:只拷贝引用,不深拷贝对象
对于 String[]、User[] 这类引用数组,System.arraycopy 复制的是每个元素的引用地址,源和目标数组指向同一堆对象。修改某个对象属性,两边都能看到变化。
- 需要真正隔离数据时,得配合 clone() 或构造新对象逐个赋值
- 基本类型数组(int[]、double[])不存在该问题,拷贝后完全独立
- 如果目标数组是 new 出来的,且后续不再复用,记得及时让 GC 回收旧引用
替代方案对比:什么时候不该用 arraycopy
虽然 arraycopy 快,但不是万能解。以下情况建议换方式:
- 源数组为 null → 先判空,否则直接 NPE
- 需要扩容+拷贝(如 ArrayList 内部扩容)→ 用 Arrays.copyOf,它内部调 arraycopy 且自动 new 新数组
- 要过滤、转换后再拷贝 → for 循环或 Stream 更清晰,别硬套 arraycopy
- 跨进程或序列化场景 → arraycopy 无效,改用 ObjectOutputStream 或 JSON 序列化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










