preface

Make writing a habit together! This is the fifth day of my participation in the “Gold Digging Day New Plan ยท April More text Challenge”. Click here for more details.

What would you say if you were asked, “What do you understand about deep copy and light copy?” There may be many friends do not understand the meaning and difference between deep copy and shallow copy, so today I would like to share with you my understanding of both ๐Ÿ˜Š.

copy

Copying, as the name suggests, is to get the same object without having to create and assign it manually. Object Copy in Java refers to copying all properties of one Object to another Object of the same class type. Let’s take a small example ๐Ÿ‘‡

There are two objects: object A and object B. Both objects belong to class XX, and both object A and object B have attributes A and B. The operation procedure for copying object A to object B is as follows: B.a = A.a; B.b = A.b;

Copying is often used when developing applications, mainly to reuse some (or all) of the data of existing objects in a new context. There are two main types of object Copy in Java: Shallow Copy and Deep Copy.

๐Ÿ“๐Ÿ“ Shallow copy ๐Ÿ“๐Ÿ“

First let’s take a look at what shallow copy means ๐Ÿ‘‡

๐Ÿฅ shallow copy ๐Ÿฅ : passes values to the basic data type and makes reference-passing copies to the reference data type.

This may not be easy to understand, but let’s paraphrase it a little bit. For a member variable whose data type is the basic data type, the shallow copy directly transfers the value, that is, copies the attribute value to the new object. Because there are two different copies of data, modifying the value of the member variable in one object does not affect the data copied from the other object. For a data type is a member of the reference data type variables, such as the member variable is an array or object of a class, etc., the shallow copy will be for reference, that is just the reference value of the member variable (that is, the memory address) a copy to the new object, also said the two different objects of the member variables point to the same address, Changing the member variable in one object affects the data copied from the other. As shown in the following figure ๐Ÿ‘‡

The clone() method can be overridden by implementing the Cloneable interface for the classes to be copied. Let’s look at the sample code:

/** * simulates the reference object *@description: Subject
 * @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:43 * * /
public class Subject {

    private String name;

    public Subject(String name) {
        this.name = name;
    }

    public String getName(a) {
        return name;
    }

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

    @Override
    public String toString(a) {
        return "Subject{" +
                "name='" + name + '\' ' +
                '} '; }}Copy the code
/** ** class *@description: Person
 * @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:43 * * /
public class Person implements Cloneable {
    /** * references the data type */
    private Subject subject;

    /** * Base data type */
    private String name;

    /** * Base data type */
    private int age;

    public Subject getSubject(a) {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    public String getName(a) {
        return name;
    }

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

    public int getAge(a) {
        return age;
    }

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

    /** * Rewrite the clone() method *@return* /
    @Override
    public Object clone(a) {
        / / shallow copy
        try {
            // Call the clone() method of the parent directly
            return super.clone();
        } catch (CloneNotSupportedException e) {
            return null; }}@Override
    public String toString(a) {
        return "[Person: " + this.hashCode() + ",subject:" + subject + ",name:" + name + ",age:" + age + "]"; }}Copy the code
/ * * *@description: Test
 * @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:49 * * /
public class Test {
    public static void main(String[] args) {
        Subject subject = new Subject("Zhang");
        Person personA = new Person();
        personA.setSubject(subject);
        personA.setName("Bill");
        personA.setAge(20);

        Person personB = (Person) personA.clone();
        personB.setName("Fifty");
        personB.setAge(18);
        Subject subjectB = personB.getSubject();
        subjectB.setName("Daisy");
        System.out.println("PersonA:" + personA.toString());
        System.out.println("PersonB:"+ personB.toString()); }}Copy the code

PersonB is copied from personA. Clone (), but personA and PersonB are two different objects. Changes to the underlying data types of personA and personB do not affect each other, and when the value of the reference subject is changed, the subject of the other object also changes.

๐Ÿ“๐Ÿ“ deep copy ๐Ÿ“๐Ÿ“

If we only want to modify the personA subject object, but the personB subject object is also modified, isn’t that a data security problem? So in some cases we need to use deep copy. Let’s first look at what deep copy means ๐Ÿ‘‡

๐Ÿฅ deep copy ๐Ÿฅ : Passes values to the base data type, creates a new object for the reference data type, and copies its contents.

Deep copy has the following characteristics:

  1. For member objects of primitive data types, attribute values are assigned directly to the new object. A basic type of copy in which one object changes the value without affecting the other (as in a shallow copy).
  2. For reference types, such as arrays or class objects, deep copy creates a new object space and copies its contents, so they point to different memory Spaces. Changing one has no effect on the other (unlike shallow copy).
  3. For multiple layers of objects, Cloneable override clone() is required for each object, thus realizing serial layer copies of objects.
  4. Deep copy is slower and more expensive than shallow copy.

Now let’s modify the shallow copy code posted above to simulate the implementation of deep copy ๐Ÿ‘‡

/** * simulates the reference object *@description: Subject
 * @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:43 * * /
public class Subject implements Cloneable{

    private String name;

    public Subject(String name) {
        this.name = name;
    }

    public String getName(a) {
        return name;
    }

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

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

    @Override
    public String toString(a) {
        return "Subject{" +
                "name='" + name + '\' ' +
                '} '; }}Copy the code
/** ** class *@description: Person
 * @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:43 * * /
public class Person implements Cloneable {
    /** * references the data type */
    private Subject subject;

    /** * Base data type */
    private String name;

    /** * Base data type */
    private int age;

    public Subject getSubject(a) {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    public String getName(a) {
        return name;
    }

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

    public int getAge(a) {
        return age;
    }

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

    /** * Overwrite the clone() method * if the Subject class also has reference objects, then we need to implement deep copy like the Person class *@return* /
    @Override
    public Object clone(a) {
        / / copy
        try {
            Person person = (Person) super.clone();
            person.subject = (Subject) subject.clone();
            return person;
        } catch (CloneNotSupportedException e) {
            System.out.println(e.toString());
            return null; }}@Override
    public String toString(a) {
        return "[Person: " + this.hashCode() + ",subject:" + subject + ",name:" + name + ",age:" + age + "]"; }}Copy the code
/ * * *@description: Test
 * @author: Zhuang Ba. Liziye *@create: the 2022-03-31 15:49 * * /
public class Test {
    public static void main(String[] args) {
        Subject subject = new Subject("Zhang");
        Person personA = new Person();
        personA.setSubject(subject);
        personA.setName("Bill");
        personA.setAge(20);

        Person personB = (Person) personA.clone();
        personB.setName("Fifty");
        personB.setAge(18);
        Subject subjectB = personB.getSubject();
        subjectB.setName("Daisy");
        System.out.println("PersonA:" + personA.toString());
        System.out.println("PersonB:"+ personB.toString()); }}Copy the code

We can see from the result that after deep-copy objects, the modification of one object’s underlying data type variable or reference type member variable will not affect the other object.

We may not often use copy when developing applications, but distinguishing deep copy from shallow copy will give us a deeper understanding of the Java memory structure and how it works ๐Ÿ’ช.

summary

My experience is limited, some places may not be particularly in place, if you think of any questions when reading, welcome to leave a message in the comments section, we will discuss one by one ๐Ÿ™‡

Please take a thumbs up and a follow (โœฟโ—กโ€ฟโ—ก) for this article ~ a crab (โ—’โ—ก’โ—)

If there are mistakes in the article, welcome to comment correction; If you have a better, more unique understanding, you are welcome to leave your valuable ideas in the comments area.

Love what you love, do what you do, listen to your heart and ask nothing