Java数组clone()默认是浅克隆:基本类型数组(如int[])值完全独立,等效深克隆;引用类型数组(如String[]、Person[])仅复制引用,共享对象;多维数组只克隆外层。

Java 数组的 clone() 默认就是浅克隆,但对一维基本类型数组(如 int[])来说,效果等同于深克隆;而对引用类型数组(如 String[] 或 Person[]),它只复制引用,不复制元素对象本身。真正需要深克隆时,不能依赖数组原生 clone(),得结合对象本身的克隆能力或序列化等手段。
数组 clone 的实际行为与限制
数组是 Java 中唯一能直接调用 clone() 且无需实现 Cloneable 的“内置类”。它的 clone() 方法由 JVM 直接支持,行为固定:
- 对
int[]、double[]等基本类型数组:逐个复制值,新旧数组完全独立,修改互不影响 - 对
String[]、Object[]、Person[]等引用类型数组:复制的是每个元素的引用地址,不是元素对象本身 - 对二维及以上数组(如
int[][]):仅克隆最外层数组,内层数组仍共享——这是典型的浅克隆嵌套表现
手动实现对象数组的深克隆
当数组元素是可变对象(如 Person、Address),且需确保副本完全隔离,推荐在数组克隆后,再对每个元素单独深克隆:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 若元素类已支持深克隆(如重写了
clone()并递归克隆字段),可用循环调用:newArray[i] = (Person) original[i].clone(); - 若元素不可变(如
String、LocalDateTime),则引用共享无风险,一维String[]克隆后可直接使用 - 避免简单写
Arrays.copyOf(persons, persons.length)—— 它本质仍是浅克隆,和persons.clone()行为一致
通用深克隆方案:绕过 clone() 的可靠做法
相比手写递归克隆,更健壮、适用性更广的深克隆方式有:
立即学习“Java免费学习笔记(深入)”;
-
序列化+反序列化:要求所有嵌套对象都实现
Serializable,适合配置类、DTO 等结构稳定场景 -
JSON 工具序列化(如 Jackson/Gson):将对象转 JSON 再解析成新实例,不依赖
Serializable,但要求无循环引用、构造函数可访问 -
第三方库(如 Apache Commons Lang 的
SerializationUtils.clone()或 DeepClone 库):封装了序列化细节,一行代码完成深克隆
为什么建议慎用 Object.clone() 体系
原生 clone() 机制存在多个硬伤:
- 必须实现
Cloneable接口,但该接口无方法,语义模糊,易被忽略 - 异常处理繁琐:
CloneNotSupportedException是检查异常,强制 try-catch 或抛出 - 子类继承时容易漏掉字段克隆,导致部分状态未复制(尤其是添加新字段后)
- final 字段无法在
clone()中重新赋值,限制设计灵活性

















