Java深克隆
在Java编程中,有时我们需要复制一个对象,并且希望这个新对象与原对象完全独立,即使原对象发生改变,新对象也不会受到影响。这时,我们可以使用深克隆(deep clone)的技术来实现。
什么是深克隆
深克隆是指在复制一个对象时,不仅复制对象本身,还要复制对象引用的其他对象。也就是说,通过深克隆创建的新对象与原对象之间的引用是相互独立的。
与深克隆相对应的是浅克隆(shallow clone),浅克隆只复制对象本身,不复制对象引用的其他对象。所以,在浅克隆中,新对象与原对象之间共享同一个对象引用,当其中一个对象改变时,另一个对象也会受到影响。
如何进行深克隆
在Java中,要实现深克隆,可以通过两种方式:实现Cloneable接口和使用序列化。
实现Cloneable接口
Cloneable接口是Java提供的一个标记接口,表示该类可以被克隆。当一个类实现了Cloneable接口,我们就可以调用其clone方法来进行对象的克隆。
public class Person implements Cloneable {
private String name;
private Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public Address getAddress() {
return address;
}
@Override
public Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.address = (Address) address.clone();
return cloned;
}
}
public class Address implements Cloneable {
private String city;
private String street;
public Address(String city, String street) {
this.city = city;
this.street = street;
}
public String getCity() {
return city;
}
public String getStreet() {
return street;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Main {
public static void main(String[] args) {
Address address = new Address("Beijing", "Main Street");
Person person1 = new Person("John", address);
try {
Person person2 = (Person) person1.clone();
System.out.println(person1.getName());
System.out.println(person1.getAddress().getCity());
System.out.println(person1.getAddress().getStreet());
System.out.println(person2.getName());
System.out.println(person2.getAddress().getCity());
System.out.println(person2.getAddress().getStreet());
person1.getAddress().setCity("Shanghai");
System.out.println(person1.getAddress().getCity());
System.out.println(person2.getAddress().getCity());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
在上面的代码示例中,我们定义了一个Person类和一个Address类。Person类中包含了一个Address对象的引用。在Person类的clone方法中,我们不仅调用了super.clone()来克隆Person对象本身,还手动克隆了Address对象。这样,当我们克隆一个Person对象时,新对象的Address引用将指向一个全新的Address对象,从而实现了深克隆。
使用序列化
另一种实现深克隆的方式是使用序列化(serialization)。通过将对象写入流中,然后再从流中读取出来,我们可以创建一个与原对象相同的新对象。
import java.io.*;
public class Person implements Serializable {
private String name;
private Address address;
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public Address getAddress() {
return address;
}
public Person deepClone() {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (Person) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
public class Address implements Serializable {
private String city;
private String street;
public Address(String city, String