Java对象深拷贝的常用方法主要有以下几种:
1. 通过实现 Cloneable
接口并重写 clone()
方法(手动实现深拷贝)
class Address implements Cloneable {
String city;
public Address(String city) {
this.city = city;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
// 深拷贝Address对象
cloned.address = (Address) address.clone();
return cloned;
}
}
public class DeepCopyDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Address addr = new Address("Beijing");
Person p1 = new Person("Tom", addr);
Person p2 = (Person) p1.clone();
p2.address.city = "Shanghai";
System.out.println(p1.address.city); // Beijing,说明深拷贝成功
System.out.println(p2.address.city); // Shanghai
}
}
2. 使用序列化实现深拷贝(适合对象及其引用都实现了Serializable
)
import java.io.*;
public class DeepCopyUtil {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T deepCopy(T obj) {
try (
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)
) {
oos.writeObject(obj);
oos.flush();
try (
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis)
) {
return (T) ois.readObject();
}
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("深拷贝失败", e);
}
}
}
使用示例:
import java.io.Serializable;
class Address implements Serializable {
String city;
public Address(String city) { this.city = city; }
}
class Person implements Serializable {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
}
public class Demo {
public static void main(String[] args) {
Person p1 = new Person("Tom", new Address("Beijing"));
Person p2 = DeepCopyUtil.deepCopy(p1);
p2.address.city = "Shanghai";
System.out.println(p1.address.city); // Beijing
System.out.println(p2.address.city); // Shanghai
}
}
3. 使用第三方库(如 Apache Commons Lang 的 SerializationUtils)
import org.apache.commons.lang3.SerializationUtils;
Person p2 = SerializationUtils.clone(p1);
注意:对象必须实现 Serializable
。
4. 手动复制(自定义拷贝构造函数)
适用于对性能有较高要求,且对象结构明确时。
class Address {
String city;
public Address(String city) { this.city = city; }
public Address(Address other) {
this.city = other.city;
}
}
class Person {
String name;
Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
public Person(Person other) {
this.name = other.name;
this.address = new Address(other.address);
}
}
总结
- 序列化深拷贝 简单快捷,但性能相对较低,且要求对象可序列化。
- 实现
Cloneable
手动深拷贝 适合复杂对象,但代码较复杂。 - 第三方库辅助 适合快速开发。
- 自定义构造函数拷贝 性能较高且可控。
需要我帮你写完整的深拷贝示范代码或者其它相关实现吗?
发表回复