一、基本概念:引用与值的复制
在 Java 中,对象的复制分为浅拷贝(Shallow Copy)和深拷贝(Deep Copy) 。
- 浅拷贝:只复制对象本身和其基本类型字段的值。对于引用类型字段,只复制引用地址,而不复制引用的对象。
- 深拷贝:彻底复制对象和其引用的所有对象。复制后的对象与原始对象在内存中完全独立。
二、浅拷贝:Object.clone()的底层实现
1. 工作原理
Object.clone()是一个native方法。它的底层实现是直接在堆中分配一个新对象,然后按位将原始对象的内存内容复制到新对象中。- 内存结构:浅拷贝后,新对象和原始对象会共享引用的对象。修改新对象的引用类型字段,会影响到原始对象。
2. Cloneable接口的真相
Cloneable是一个标记接口,它不包含任何方法。它的作用是告诉 JVM,该对象可以被安全地克隆。- 如果一个类没有实现
Cloneable接口,调用其Object.clone()方法会抛出CloneNotSupportedException。
三、深拷贝:手动实现与序列化
深拷贝是 Java 编程中的一个常见需求,它需要开发者手动实现。
1. 手动实现
-
原理:在
clone()方法中,除了调用super.clone()外,还需要手动递归地克隆所有引用类型字段。 -
示例:
@Override protected Object clone() throws CloneNotSupportedException { Resume clone = (Resume) super.clone(); clone.work = (WorkExperience) work.clone(); // 手动深拷贝引用对象 return clone; }
2. 序列化实现
- 原理:通过将对象序列化为字节流,再反序列化为新对象,从而实现深拷贝。
- 要求:所有对象都必须实现
Serializable接口。 - 优缺点:实现简单,但性能较差(涉及到 I/O 和反射)。
四、性能与选型指南
| 方式 | 优点 | 缺点 |
|---|---|---|
Object.clone() | 速度快,无需调用构造函数。 | 需要实现 Cloneable 接口;代码繁琐。 |
| 序列化 | 自动处理所有引用,无需递归。 | 性能差,需要实现 Serializable 接口。 |
| 拷贝构造函数 | 安全,可控制构造过程。 | 需手动编写构造函数,代码量大。 |
结论:
Object.clone()实现了浅拷贝。- 深拷贝需要手动实现递归克隆,或通过序列化机制。
String由于其不可变特性,浅拷贝是安全的。- 在实际开发中,应根据业务需求和性能考量,选择合适的拷贝方式。