浅拷⻉:
浅拷⻉会在堆上创建⼀个新的对象(区别于引⽤拷⻉的⼀点),不过,如果原对象内部的属性是引⽤类型的话,浅拷⻉会直接复制内部对象的引⽤地址,也就是说拷⻉对象和原对象共⽤同⼀个内部对象。
深拷⻉ :
深拷⻉会完全复制整个对象,包括这个对象所包含的内部对象。
我们知道在Java中存在这个接口Cloneable,实现该接口的类都会具备被拷贝的能力。
如何实现深拷贝(深克隆)?
示例代码
class Person implements Cloneable {
String name;
int age;
Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person clonedPerson = (Person) super.clone();
clonedPerson.address = (Address) this.address.clone();
return clonedPerson;
}
}
class Address implements Cloneable {
String city;
String state;
public Address(String city, String state) {
this.city = city;
this.state = state;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
}
public class DeepCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("San Francisco", "CA");
Person person1 = new Person("John", 30, address);
Person person2 = (Person) person1.clone();
System.out.println("Person1 address: " + person1.address.city); // 输出: San Francisco
System.out.println("Person2 address: " + person2.address.city); // 输出: San Francisco
person2.address.city = "Los Angeles";
System.out.println("Person1 address after modification: " + person1.address.city); // 输出: San Francisco
System.out.println("Person2 address after modification: " + person2.address.city); // 输出: Los Angeles
}
}
注意以上是实现了cloneable接口。当然这种方法实在是太过于麻烦了。使用序列化来深克隆一个对象要简单得多,尤其是成员变量中有很多引用类型的时候。
使用序列化和反序列化来深拷贝一个对象
import java.io.*;
// 地址类实现Serializable接口
class Address implements Serializable {
String city;
String state;
public Address(String city, String state) {
this.city = city;
this.state = state;
}
@Override
public String toString() {
return city + ", " + state;
}
}
// 人类实现Serializable接口
class Person implements Serializable {
String name;
int age;
Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
public String toString() {
return name + " (" + age + "), " + address;
}
// 使用序列化进行深拷贝
public Person deepCopy() throws IOException, ClassNotFoundException {
// 将对象写入字节流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
oos.flush();
oos.close();
// 从字节流读取对象
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Person) ois.readObject();
}
}
public class DeepCopyUsingSerialization {
public static void main(String[] args) {
try {
Address address = new Address("San Francisco", "CA");
Person person1 = new Person("John", 30, address);
// 深拷贝person1
Person person2 = person1.deepCopy();
System.out.println("Person1: " + person1); // 输出: John (30), San Francisco, CA
System.out.println("Person2: " + person2); // 输出: John (30), San Francisco, CA
// 修改person2的地址
person2.address.city = "Los Angeles";
System.out.println("Person1 after modification: " + person1); // 输出: John (30), San Francisco, CA
System.out.println("Person2 after modification: " + person2); // 输出: John (30), Los Angeles, CA
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
如果觉得有帮助,欢迎点赞、收藏,以及小小支持一下。
本人博客地址:朗朗繁星的博客