java如何复制
浅拷贝与深拷贝的基本概念
在Java中,复制对象分为浅拷贝和深拷贝两种方式。
- 浅拷贝:复制对象的基本字段值,但引用类型的字段仍指向原对象的引用。
- 深拷贝:完全复制对象及其引用的所有对象,生成一个完全独立的副本。
实现浅拷贝的方法
1. 使用 clone() 方法
类需实现 Cloneable 接口并重写 clone() 方法:
class Person implements Cloneable {
String name;
int age;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
// 使用示例
Person p1 = new Person();
Person p2 = (Person) p1.clone();
注意:clone() 默认是浅拷贝,若字段为引用类型(如数组、对象),复制后的对象与原对象共享该引用。
2. 通过构造函数复制
直接在构造函数中传入原对象的字段值:

class Person {
String name;
int age;
Person(Person other) {
this.name = other.name;
this.age = other.age;
}
}
// 使用示例
Person p1 = new Person();
Person p2 = new Person(p1);
实现深拷贝的方法
1. 手动实现深拷贝
递归复制所有引用类型的字段:
class Address implements Cloneable {
String city;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable {
String name;
Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) address.clone(); // 深拷贝Address
return cloned;
}
}
2. 使用序列化与反序列化
通过序列化将对象转换为字节流,再反序列化生成新对象:

import java.io.*;
class Person implements Serializable {
String name;
Address address;
Person deepCopy() throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Person) ois.readObject();
}
}
要求:所有涉及的类必须实现 Serializable 接口。
第三方工具库
Apache Commons Lang
使用 SerializationUtils.clone() 实现深拷贝:
import org.apache.commons.lang3.SerializationUtils;
Person p1 = new Person();
Person p2 = SerializationUtils.clone(p1);
需添加依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
注意事项
- 性能:深拷贝比浅拷贝开销更大,尤其是对象图复杂时。
- 不可变对象:如
String、基本类型包装类,浅拷贝即可满足需求。 - 循环引用:深拷贝需处理循环引用问题,避免栈溢出。






