小问题6 | Java中如何实现深拷贝?实现深拷贝的三种方法
前置问题:小问题4 | Arrays.copyOf(elementData, size, a.getClass())是如何实现的?
1. 实现 Cloneable 接口并重写 clone() 方法
对象的 clone 方法默认是浅拷贝,若想实现深拷贝,就需要重写 clone 方法实现属性对象的拷贝。
想实现深拷贝,需要为对象中每一层的每一个对象都实现Clonneable接口(对该接口不熟悉的朋友可以看下面的补充),并重写clone方法,最后在最顶层类的重写的clone方法中,调用所有的clone方法。
简单的说,每层的每个对象都进行浅拷贝=深拷贝。
下面是一个代码示例(在代码示例中,我们省略构造器和getter/setter):
/**
* 用户
*/
public class User implements Cloneable {
private String name;
private Address address;
@Override
public User clone() throws CloneNotSupportedException {
User user = (User) super.clone();
user.setAddress(this.address.clone());
return user;
}
}
/**
* 地址
*/
public class Address implements Cloneable {
private String city;
private String country;
@Override
public Address clone() throws CloneNotSupportedException {
return (Address) super.clone();
}
}
2. 使用序列化和反序列化实现深拷贝
序列化是将对象转换为字节流的过程,以便可以将其保存到磁盘文件、通过网络传输或在内存中保存。
序列化将对象的状态以二进制形式编码,以便稍后可以重新创建对象,这个过程称为反序列化。
序列化在 Java 中有许多应用,其中之一是实现深拷贝。
让我们使用和上文相同的两个类,这次让他们实现Serializable :
/**
* 用户
*/
public class User implements Serializable {
private String name;
private Address address;
// 省略构造器和getter/setter
}
/**
* 地址
*/
public class Address implements Serializable {
private String city;
private String country;
// 省略构造器和getter/setter