Java Common Design Patterns——Prototype Patterns (2) Deep Copy and Shallow Copy

introduction

clone, as the name implies, is to copy. In the Java language, the clone method is called by the object, so the object will be copied. The so-called copy object first allocates a space of the same size as the source object, and creates a new object in this space. So in the java language, there are several ways to create objects? 

1 Use the new operator to create an object 

2 Use the clone method to copy an object 

So what are the similarities and differences between these two methods? The purpose of the new operator is to allocate memory. When the program executes the new operator, it first looks at the type behind the new operator, because only by knowing the type can it know how much memory space to allocate. After allocating the memory, call the constructor to fill in the various fields of the object. This step is called initialization of the object. After the constructor returns, an object is created, and its reference (address) can be published to the outside, which can be used outside. This reference manipulates this object. The first step of clone is similar to new, it allocates memory. When calling the clone method, the allocated memory is the same as the source object (that is, the object that calls the clone method), and then uses the corresponding fields in the original object to fill in After the field of the new object is filled, the clone method returns, a new identical object is created, and a reference to this new object can also be released to the outside world. [ Detailed explanation of the clone method in Java ]

Kind of copy

reference copy

package design.pattern.copy;
/**
 * reference copy
 * <br>类名:CiteCopy<br>
 * Author: mht<br>
 * Date: April 1, 2018 - 6:13:37pm<br>
 */
public class CiteCopy {

    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = s1;
        System.out.println(s1 + "\n" + s2);
    }
}

result:

design.pattern.copy.Student@6d06d12f
design.pattern.copy.Student@6d06d12f


object copy

package design.pattern.copy;
/**
 * object copy
 * <br>类名:Copy<br>
 * Author: mht<br>
 * Date: April 1, 2018 - 6:13:37pm<br>
 */
public class Copy {

    public static void main(String[] args) {
        Student s1 = new Student();
        Student s2 = (Student) s1.clone();
        System.out.println(s1 + "\n" + s2);
    }
}

result:

design.pattern.copy.Student@15db9742
design.pattern.copy.Student@6d06d69c

shallow copy

package design.pattern.copy;
/**
 * Shallow copy
 * <br>类名:Copy<br>
 * Author: mht<br>
 * Date: April 1, 2018 - 6:13:37pm<br>
 */
public class Copy {

    public static void main(String[] args) {
        Student s1 = new Student();
        Teacher t1 = new Teacher();
        s1.setTeacher(t1);
        System.out.println("memory address of t1: " + t1);
        Student s2 = (Student) s1.clone();
        // The memory of the two student objects is:
        System.out.println(s1 + "\n" + s2);
        // The teacher object in the two student objects is:
        System.out.println(s1.getTeacher() + "\n" +  s2.getTeacher());
    }
}

result:

Memory address of t1: design.pattern.copy.Teacher@15db9742
design.pattern.copy.Student@6d06d69c
design.pattern.copy.Student@7852e922
design.pattern.copy.Teacher@15db9742
design.pattern.copy.Teacher@15db9742

deep copy

        The copy implemented by clone is a shallow copy by default, that is, only the object that calls the clone method is copied, and the member variable objects referenced inside the object will not be copied together. Therefore, even if the internal object is cloned again Copy, there will still be a problem that the internal reference object of the internal object is not copied. Therefore, in general, clone can achieve an incomplete deep copy, but cannot achieve a complete deep copy.

        Implementing a deep copy through Serializable will truly replicate the entire object.

package design.pattern.copy;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Student implements Serializable{
    private String name;
    private int age;
    private 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;
    }
    
    /**
     * deep copy
     * <br>作者: mht<br>
     * Time: April 1, 2018 - 10:53:41 pm<br>
     * @return
     */
    protected Object deepClone(){
        try {
            // Serialization
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            // deserialize
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            
            return ois.readObject();
        } catch (IOException e) {
            e.printStackTrace ();
        } catch (ClassNotFoundException e) {
            e.printStackTrace ();
        }
        
        return null;
    }
}
package design.pattern.copy;

import java.io.Serializable;

public class Teacher implements Serializable{
    private String name;
    private int age;
    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;
    }
}
package design.pattern.copy;
/**
 * Serializable serialize deep copy
 * <br>类名:Copy<br>
 * Author: mht<br>
 * Date: April 1, 2018 - 6:13:37pm<br>
 */
public class Copy {

    public static void main(String[] args) {
        Student s1 = new Student();
        Teacher t1 = new Teacher();
        s1.setTeacher(t1);
        System.out.println("memory address of t1: " + t1);
        System.out.println("==========================");
        Student s2 = (Student) s1.deepClone();
        // The memory of the two student objects is:
        System.out.println(s1 + "\n" + s2);
        System.out.println("==========================");
        // The teacher object in the two student objects is:
        System.out.println("s1.getTeacher() : " + s1.getTeacher() + "\ns2.getTeacher() : " +  s2.getTeacher());
    }
}

result:

Memory address of t1: design.pattern.copy.Teacher@15db9742
==========================
design.pattern.copy.Student@3d4eac69
design.pattern.copy.Student@232204a1
==========================
s1.getTeacher() : design.pattern.copy.Teacher@15db9742
s2.getTeacher() : design.pattern.copy.Teacher@4aa298b7

It can be seen from the above results that not only the student object is copied, but the teacher object inside s1 is also copied to a new object. However, it should be noted that the Teacher class must also implement the Serializable interface, otherwise a runtime exception of NotSerializableException will be generated.



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325340143&siteId=291194637