前言
深拷贝:在进行赋值之前,为指针类型的数据成员另辟了一个独立的内存空间,实现真正内容上的拷贝 。这种拷贝称为深拷贝。
深拷贝的两种实现方式
- 实现Cloneable接口,重写Object类中clone()方法,实现层层克隆的方法。
- 通过序列化(Serializable)的方法,将对象写到流里,然后再从流中读取出来。虽然这种方法效率很低,但是这种方法才是真正意义上的深度克隆。
序列化与反序列化
序列化:把对象转换为字节序列的过程称为对象的序列化。
反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
实例
-
先构造一个学生对象。值得注意的是,被序列化的对象的类同样也必须要实现Serializable接口,否则将会抛出NotSerializableException异常。
import java.io.Serializable; /** * @author CodeLuo * @date 2021/7/7 22:20 */ public class Student implements Serializable{ private String name; private String address; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", address='" + address + '\'' + ", sex='" + sex + '\'' + '}'; } } 复制代码 -
然后创建实现深拷贝的类StudentClone.java
import java.io.*; /** * @author CodeLuo * @date 2021/7/7 22:17 */ public class StudentClone implements Serializable { public static Student myClone(Student student){ Student anotherStu = null; try { //在内存中开辟一块缓冲区,将对象序列化成流 ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bout); out.writeObject(student); //找到这一块缓冲区,将字节流反序列化成另一个对象 ByteArrayInputStream bais = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); anotherStu = (Student) ois.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } return anotherStu; } } 复制代码测试
测试方法就是创建一个student对象和一个空对象,通过调用拷贝方法将student的属性深拷贝到anotherStudnet。
public static void main(String[] args) { Student student = new Student(); student.setName("张三"); student.setAddress("地球"); student.setSex("男"); System.out.println("第一个学生:"+student); Student anotherStudent = null; System.out.println("深拷贝前的第二个学生:"+anotherStudent); anotherStudent = myClone(student); System.out.println("深拷贝后的第二个学生:"+anotherStudent); } 复制代码测试结果
程序运行后,测试出的结果如下图所示,成功完成拷贝。

注意
- 若序列化对象的类中不实现Serializable接口,就会出现上诉中出现的NotSerializableException异常。如下图所示。

-
如果说在业务需求方面,不希望对象的某个属性被序列化。比如说涉及敏感的的身份证号或者手机号码。当然敏感信息也可以做加密处理,哈哈。说会正题,这种情况下可以通过在属性前添加transient关键字。
private String name; private String address; //假设这次不希望性别被复制过去。 private transient String sex; 复制代码

© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)