Java数组深拷贝需依类型选择策略:基本类型用clone()或System.arraycopy()即得深拷贝;对象数组默认浅拷贝,需手动递归克隆或改用不可变设计。

Java 数组深拷贝不是选“要不要”,而是选“怎么克、克多深、何时克”。基本类型数组(如 int[])用 clone() 或 System.arraycopy() 就是真正独立副本;但对象数组(如 Person[]、String[])默认只复制引用——表面克隆成功,实则共享对象实例,改一个,另一个也变。
clone() 看似简洁,实际限制多
clone() 对一维基本类型数组安全高效,写法最简:int[] b = a.clone();。但它对对象数组仍是浅拷贝,且性能较差:实测速度约为 System.arraycopy() 的 1/9–1/10,尤其在大数组(如 byte[] 百万级)场景下差距明显。更关键的是,它无法自动处理嵌套对象——比如 Person[] 中每个 Person 若含可变字段,必须手动递归调用其 clone() 方法,否则仍属浅拷贝。
- 不支持部分拷贝,只能复制整个数组
- 二维数组调用
arr.clone()只复制第一层引用,arr[i]仍指向原对象 - 要求元素类型实现
Cloneable接口,否则运行时抛异常
System.arraycopy() 是性能首选,但需手动准备
这是 JVM 内部优化的底层操作,绕过边界检查、支持 SIMD 向量化,中大型数组(数千元素起)拷贝最快。它本身不分配内存,所以必须提前创建目标数组,且类型、长度需严格匹配:
int[] src = {1,2,3}; int[] dst = new int[3]; System.arraycopy(src, 0, dst, 0, src.length);- 支持任意起始偏移和长度,适合截取、拼接等场景
- 对基本类型数组天然深拷贝;对对象数组仍是浅拷贝,仅复制引用
Arrays.copyOf() 平衡简洁与效率
内部调用 System.arraycopy(),但多了新数组分配和长度计算开销,比直接 arraycopy 慢约 10–20%。优势在于写法干净、自动扩容或截断:
立即学习“Java免费学习笔记(深入)”;
-
int[] b = Arrays.copyOf(a, a.length);—— 完整拷贝 -
int[] b = Arrays.copyOf(a, 5);—— 不足补 0,超长截断 - 不适用于需要部分拷贝或动态转换的场景(如过滤、映射)
深拷贝真需求?优先考虑不可变设计
真正需要深拷贝的场景其实不多。多数数据污染问题源于可变对象被多个数组共享。比起写复杂递归克隆或序列化反序列化(代价远高于数组复制本身),更轻量安全的做法是:
- 用不可变对象替代:如
String、LocalDateTime、BigDecimal,它们本身无状态修改风险 - 构造新对象而非修改旧对象:例如
person.withName("new")返回新实例,避免副作用 - 仅当业务强依赖隔离性(如快照、回滚、并发读写)时,再引入深拷贝方案,如 JSON 序列化或 Kryo



















