深拷贝(2种实现方式)与浅拷贝的区别

195 阅读2分钟

深拷贝和浅拷贝当对象只是基本类型时没有区别。如果复制的对象中含有引用类型,浅拷贝复制的引用类型对象会指向原来的对象,这样修改浅拷贝过后的对象就会影响原来的对象。而深拷贝会给引用对象新建一个新的对象进行clone,两个对象互不影响。

  • 第一种方式:实现Cloneable接口,重写clone方法的时候对引用类型变量要进行单独的clone。
  • 第二种方式:实现Serializable接口,通过流对象进行写入。
package 深拷贝与浅拷贝;

import java.io.*;

public class DeepCopy {
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        //1.通过实现cloneable接口来实现深拷贝,即在把基本类型clone后将引用对象类型还要再单独clone一次
        Student s1 = new Student(10, "zhangsan", new School(9, "九中"));
        Student s2 = s1.clone();
        System.out.println(s1);
        System.out.println(s2);
        //如果school不重写clone方法,则s2获取到的school对象和s1是指向的同一个
        s2.getSchool().setGrade(111);
        System.out.println(s1);
        System.out.println(s2);

        //2.序列化方式实现深拷贝
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(s1);
        oos.close();

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);

        Student student = (Student) ois.readObject();
        ois.close();

        System.out.println(student);

    }
}

class Student implements Cloneable, Serializable {
    private static final long serialVersionUID = 2631590509760908280L;

    private int age;
    private String name;
    private School school;

    public Student(int age, String name, School school) {
        this.age = age;
        this.name = name;
        this.school = school;
    }

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Student clone() throws CloneNotSupportedException {
        Student clone = (Student) super.clone();
        //这里实现深拷贝,将引用类型对象进行clone
        clone.school = school.clone();
        return clone;
    }
}

class School implements Cloneable,Serializable{
    private static final long serialVersionUID = 2631590509760908289L;
    private int grade;
    private String schoolName;

    public School(int grade, String schoolName) {
        this.grade = grade;
        this.schoolName = schoolName;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }


    public String getSchoolName() {
        return schoolName;
    }

    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }
    

    @Override
    protected School clone() throws CloneNotSupportedException {
        return (School)super.clone();
    }
}