Principle and Implementation of Java Deep Cloning and Shallow Cloning

Why clone

First think about a question, why do we need to clone an object? Isn't it possible to create an object directly?

The cloned object may contain some modified properties, and the properties of the new object are still the initial values, so when a new object is needed to save the "state" of the current object, it is necessary to clone.

Of course, it is also possible to assign the properties of the object to the new new object one by one, but this is troublesome, and secondly, we can view the clone method of the Object through the source code as a native method (the native method is implemented in a non-Java language Code, for Java programs to call, there is no way to access the lower level of the operating system, it can only be implemented in a language close to the operating system), it is fast, and it is implemented at a lower level.

Our common Object a = new Object(); Object b; b = a; This form of code copies is a reference, that is, the address of the object in memory, a and b point to the same object. The value is assigned through the clone method The object of and the original object exist independently at the same time.

concept

Shallow clone: All variable values ​​in the cloned object are the same as the original object, and all references to other objects still point to the original object. Simply put, shallow clone only clones the current object, not what the current object refers to Object.

Deep cloning: All the variable values ​​in the cloned object are the same as the original object. Those variables that refer to other objects will point to the new object that has been copied instead of the original referenced object. Simply put, deep cloning is not only The current object is cloned, and all the objects referenced by the current object are copied.

Image source: https://blog.csdn.net/lovezhaohaimig/article/details/80372233 

Clone in Object

The clone() method in the Object class is a shallow clone. Its working principle is as follows: first create a space in memory that is the same as the original object, and then copy the content of the original object. For basic data types, this operation is of course no problem, but For reference types, since only references to objects are saved, the cloned references point to the same object.

Shallow cloning in Java

To implement clone in java, you need to implement the Cloneable interface, which is very simple and only serves as an identifier. The source code is as follows:

Shallow clone case

Student class:

package com.dgut.ssmDemo.service.impl;

/**
 * @author jcH
 * @create 2020-03-11 13:33
 */
public class Student{
    private String stuName;

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + stuName + '\'' +
                '}';
    }
}

Teacher category:

package com.dgut.ssmDemo.service.impl;

/**
 * @author jcH
 * @create 2020-03-11 13:34
 */
public class Teacher implements Cloneable{
    private String teaName;
    private Student student;

    public String getTeaName() {
        return teaName;
    }

    public void setTeaName(String teaName) {
        this.teaName = teaName;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "teaName='" + teaName + '\'' +
                ", student=" + student +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //浅拷贝
        return super.clone();
    }
}

test:

package com.dgut.ssmDemo.service.impl;

/**
 * @author jcH
 * @create 2020-03-11 13:36
 */
public class TestClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student();
        student.setStuName("张三");
        Teacher teacher1 = new Teacher();
        teacher1.setTeaName("英语老师");
        teacher1.setStudent(student);
        Teacher teacher2 = (Teacher) teacher1.clone();
        teacher2.setTeaName("语文老师");
        teacher2.getStudent().setStuName("李四");
        System.out.println(teacher1);
        System.out.println(teacher2);
    }
}

Output result:

 

Deep cloning in Java

Clone all reference types in the class, and override the object clone() method to clone all reference types.

Compared with shallow cloning, you need to: 1. Let the Student class implement the Cloneable interface; 2. Override the clone method in the Teacher class:

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //深拷贝
        Teacher teacher = (Teacher) super.clone();
        teacher.student = (Student) student.clone();
        return teacher;
    }

 Output result:

Serialization and deserialization for deep cloning

In the case of many reference data types, you can use serialization and deserialization to implement deep cloning, but this is not recommended because it consumes a lot of CPU.

How to use serialization to complete the copy of the object? Copying through byte stream in memory is relatively easy to implement. Write the parent object into a byte stream, and then read it from the byte stream, so that a new object can be created, and there is no problem of reference sharing between the new object and the parent object. Realize the deep copy of the object.

The code can refer to the following figure, provided that the operating class needs to implement the Serializable interface

Guess you like

Origin blog.csdn.net/weixin_40391011/article/details/104795425
Recommended