Deep and Shallow Copies (Objects)

Keywords: Java jvm xml Attribute

Cloneable:CloneableSupportedException
 clone() provided by the Object class can only be used if the subclass implements the Cloneable interface, otherwise the above exception will be thrown.

protected native Object clone() throws CloneNotSupportedException;


To make an object copy, we must implement Cloneable interface (identification interface, indicating that this class is allowed to be cloned), and customize clone() in the class to call the inheritance privilege clone() provided by the Object class.

1. shallow copy

Object value copy. For shallow copies, the copied object still retains all references to the original object.

Question: Pull it all together (as long as any copy object (or the reference in the original object changes, all objects will be affected).

package com.xunpu.jvm;
//Shallow copy
class Teacher{
    private String name;

    public Teacher(String name, String job) {
        this.name = name;
        this.job = job;
    }

    private String job;

    public String getName() {
        return name;
    }

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

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

class Student  implements Cloneable{
    private String name;
    private int age;
    private Teacher teacher;

    public Student clone(){
        Student student=null;
        try {
            //Implementing copy processing
            //Generate a new student object and copy all the original attribute values
            student= (Student) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return student;
    }
    public Student(String name, int age, Teacher teacher) {
        this.name = name;
        this.age = age;
        this.teacher = teacher;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
}

public class TestClone {
    public static void main(String[] args) {
        Teacher teacher=new Teacher("Zhang San","java teacher");
        Student student=new Student("boss",18,teacher);

        Student studentClone=student.clone();
        System.out.println(studentClone);
        System.out.println(student);
        System.out.println(studentClone.getName());
        System.out.println(studentClone.getAge());
        System.out.println(studentClone.getTeacher().getJob()+":"+studentClone.getTeacher().getName());
        System.out.println("===========================");
        System.out.println(student.getTeacher()==studentClone.getTeacher());//true
    }
}

Result:

Shallow copy principle:

2. deep copy

In deep copy, the copied object produces all new referenced objects.

Feature: Modifying any one object will not affect other objects.

How to achieve deep copy?

1) The other classes included continue to implement the Cloneable interface and call clone() (recursively implement clone).

2) Use serialization.

When using serialization for deep copy, Cloneable interface is no longer needed, but Serializable interface is only needed.

//Deep copy
//Implementation Method 1: The other classes included continue to implement the Cloneable interface and call clone() (recursive implementation clone).
package com.xunpu.jvm;

import com.sun.xml.internal.ws.util.xml.NamespaceContextExAdaper;

class Teacher implements Cloneable {
    private String name;

    public Teacher(String name, String job) {
        this.name = name;
        this.job = job;
    }
    public Teacher clone(){
        Teacher teacher=null;
        try {
            teacher= (Teacher) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return teacher;
    }
    private String job;

    public String getName() {
        return name;
    }

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

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

class Student  implements Cloneable{
    private String name;
    private int age;
    private Teacher teacher;

    public Student clone(){
        Student student=null;
        try {
            //Implementing copy processing
            //Generate a new student object and copy all the original attribute values
            student= (Student) super.clone();
            student.teacher=this.teacher.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return student;
    }
    public Student(String name, int age, Teacher teacher) {
        this.name = name;
        this.age = age;
        this.teacher = teacher;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
}

public class TestClone {
    public static void main(String[] args) {
        Teacher teacher=new Teacher("Zhang San","java teacher");
        Student student=new Student("boss",18,teacher);

        Student studentClone=student.clone();
        System.out.println(studentClone);
        System.out.println(student);
        System.out.println(studentClone.getName());
        System.out.println(studentClone.getAge());
        System.out.println(studentClone.getTeacher().getJob()+":"+studentClone.getTeacher().getName());
        System.out.println("===========================");
        System.out.println(student.getTeacher()==studentClone.getTeacher());//true
    }
}

Result:

//Deep copy
//Mode 2: Use serialization
package com.xunpu.jvm;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

import java.io.*;

class Teacher implements Serializable {
    private String name;

    public Teacher(String name, String job) {
        this.name = name;
        this.job = job;
    }

    private String job;

    public String getName() {
        return name;
    }

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

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

class Student  implements Serializable {
    private String name;
    private int age;
    private Teacher teacher;

    public Student cloneObject() throws Exception{
        //Serialized read and write through memory
        //Get the memory stream
        ByteOutputStream bos=new ByteOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bos);
        oos.writeObject(this);

        ByteArrayInputStream bis=new ByteArrayInputStream(bos.getBytes());
        //Getting two core classes of serialization
        ObjectInputStream ois=new ObjectInputStream(bis);

        return (Student) ois.readObject();
    }
    public Student(String name, int age, Teacher teacher) {
        this.name = name;
        this.age = age;
        this.teacher = teacher;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
}

public class TestClone {
    public static void main(String[] args) throws Exception {
        Teacher teacher=new Teacher("Zhang San","java teacher");
        Student student=new Student("boss",18,teacher);

        Student studentClone=student.cloneObject();
        System.out.println(studentClone);
        System.out.println(student);
        System.out.println(studentClone.getName());
        System.out.println(studentClone.getAge());
        System.out.println(studentClone.getTeacher().getJob()+":"+studentClone.getTeacher().getName());
        System.out.println("===========================");
        System.out.println(student.getTeacher()==studentClone.getTeacher());//true
    }
}

The results are the same.

Deep copy principle:

Posted by gplaurin on Sat, 12 Oct 2019 10:03:38 -0700