Java数组复制需按场景选方法:完整拷贝或动态调整长度用Arrays.copyOf();高性能片段搬运用System.arraycopy();对象数组深拷贝需手动clone或序列化;按范围截取用Arrays.copyOfRange()。

Java 数组复制不是简单“复制一份”就能完事的事。选错方法,轻则性能掉档、内存浪费,重则逻辑出错、数据污染。关键不在“能不能复制”,而在“怎么复制才对”——取决于你要的是完整副本、部分截取、扩容缩容,还是对象间真正的独立。
完整拷贝或动态调整长度 → 用 Arrays.copyOf()
这是最贴近日常开发直觉的方式:传入原数组和新长度,它自动创建新数组并完成复制。内部调用 System.arraycopy(),但省去了手动 new 数组的步骤,语义清晰、不易出错。
- 完整复制:
int[] copy = Arrays.copyOf(src, src.length); - 扩容(多出位置填默认值):
String[] bigger = Arrays.copyOf(src, 10);—— 长度不够时补 null - 缩容(只取前 N 个):
int[] smaller = Arrays.copyOf(src, 3);—— 超出部分直接丢弃
适用于 DTO 转换、参数快照、缓存备份等常规场景。对基本类型安全;对 String 等不可变对象也足够可靠。
高性能片段搬运或原地重排 → 用 System.arraycopy()
它是 JVM 底层优化的内存级拷贝,零对象创建开销,是性能敏感场景的首选。支持跨数组复制、同数组内移动(比如左移删除头元素),甚至能安全处理重叠区域(JVM 自动倒序执行避免覆盖)。
立即学习“Java免费学习笔记(深入)”;
- 跨数组复制:
System.arraycopy(src, 2, dest, 0, 3);→ 把 src[2]~src[4] 搬到 dest[0]~dest[2] - 同数组左移(删前3个):
System.arraycopy(arr, 3, arr, 0, arr.length - 3); - 务必校验边界:
srcPos + length ≤ src.length且destPos + length ≤ dest.length,否则抛 ArrayIndexOutOfBoundsException
适合滑动窗口、环形缓冲区、高频算法实现等对吞吐和延迟有要求的场合。
对象数组真正独立 → 别只靠 Arrays.copyOf()
Arrays.copyOf() 对 Person[] 这类数组只复制引用,不是深拷贝。改副本里的 person.name,原数组对应对象也会变。
- 若元素类已正确实现 Cloneable + clone():
copy[i] = (Person) src[i].clone();(需遍历) - 结构复杂(含 List、Date、嵌套对象):优先考虑序列化反序列化(要求可 serializable),或用 MapStruct 等工具显式定义字段映射
- 业务中常只需“半深拷贝”:数组本身新造,关键可变字段(如时间、集合)单独深拷,不必无脑递归全量克隆
按范围快速截取 → 用 Arrays.copyOfRange()
要某一段,不想要头尾冗余代码。它接受起始索引(包含)、结束索引(不包含),自动创建合适长度的新数组。
- 示例:
String[] part = Arrays.copyOfRange(words, 1, 3);→ 得到 {"b", "c"} - 比手动 new + System.arraycopy 更简洁,也比先 copy 再 slice 更安全(不会越界)
- 底层仍是 System.arraycopy(),性能无损
适合分页、日志切片、协议解析等明确需要子区间副本的场景。


















