Object类clone()默认浅拷贝,需手动深拷贝可变引用字段(如ArrayList、HashMap、POJO等),不可变类(String、LocalDateTime等)和基本类型无需深拷贝;推荐使用拷贝构造器或静态工厂方法替代clone()。

Object 类本身不提供深拷贝能力,它的 clone() 方法默认只做浅拷贝。要避免引用类型共享导致的修改污染,必须在子类中主动干预,对每个可变引用字段单独处理。
哪些字段必须手动深拷贝
不是所有字段都需要克隆,关键看是否“可变”:
- 必须深拷贝的:ArrayList、HashMap、自定义 POJO(如 Address)、Date、StringBuilder、对象数组等——它们的内容可被外部修改,共享会导致状态污染
- 无需深拷贝的:String、Integer、LocalDateTime、BigInteger 等不可变类——值安全共享,直接赋值即可
- 基本类型(int、boolean、double 等):天然值复制,不用额外操作
在 clone() 中逐字段处理引用类型
调用 super.clone() 得到的是浅拷贝结果,之后必须挨个替换可变引用字段:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
自定义对象:确保它也实现了
Cloneable并重写了public clone(),然后显式调用:cloned.address = this.address.clone(); -
集合类:
list.clone()是无效的(仍是浅拷贝),应新建集合并填充副本:cloned.hobbies = new ArrayList(this.hobbies);(若元素是 String)或遍历克隆每个可变元素 -
对象数组:不能用
addresses.clone(),需逐个克隆:cloned.addresses = Arrays.stream(this.addresses).map(Address::clone).toArray(Address[]::new); -
null 安全:所有引用字段操作前加判空,避免
NullPointerException
绕过 clone() 的更可靠方案
原生 clone() 机制有设计缺陷(与 final 字段冲突、类型不安全、易漏层级),实际项目中更推荐:
立即学习“Java免费学习笔记(深入)”;
-
拷贝构造器:清晰、可控、支持
final字段,例如public Person(Person other) { this.name = other.name; this.address = new Address(other.address); } -
静态工厂方法:语义明确,便于扩展,如
Person.copyOf(other) -
序列化反序列化:通用但要求所有字段类型都实现
Serializable,且不适用于含资源句柄、Lambda 或 transient 字段的对象
特别注意循环引用和 final 字段
当对象图存在 A→B→A 这类环状引用时,递归调用 clone() 会栈溢出。此时需引入缓存(如 IdentityHashMap)记录已克隆对象,避免重复处理。而 final 字段在 super.clone() 后无法重新赋值,直接使用 clone() 机制不可行,必须改用构造器或 builder 模式。

















