Java object cloning

What is cloning

  cloning, as the name suggests, is to clone an object's information to generate a new object. Then someone must have asked, why clone when there is new? Because the properties of new objects are initialized values, while those of clone objects can save the existing state of the object. When we need to temporarily save the existing state of an object, we can use clone. If we use new, we also need to re assign values. When there are many properties, it will be cumbersome. And clone is a native method, which interacts with the underlying operating system and will be faster.
be careful:

  • Person p = new Person; Person p1 = p; This is not an object clone. It just wants to copy the reference of the person object to p2. The two references point to the same object. In fact, they operate on the same object. What is cloned is a new object.
  • The cloned class must implement the clonable interface. The interface has no method, which is equivalent to a capability, indicating that the class implementing the interface can be cloned. Then override the clone() method in the Object class

Classification of clones

  cloning can be divided into two categories: shallow cloning and deep cloning.

Shallow cloning

   shallow clone: if the attribute of the object is basic data type or String type, copy a copy to the cloned object; If it is a reference type, the address of the reference object is copied to the clone object.

public class Person implements Cloneable{
    private int age;
    private String name;
    private Address address;

    //setter and getter omitted
    
    @Override
    public  Person clone() throws CloneNotSupportedException {
        return (Person) super.clone(); // Directly call the clone() method of the parent class without any processing
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

public class ShallowCloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person(); // person1 object
        person1.setAge(22);
        person1.setName("Zhang San");
        Address address = new Address("Beijing"); // reference type
        person1.setAddress(address);
        Person person2 = person1.clone();
        person2.getAddress().setName("Nanjing"); // Modify the name attribute of the Address object in person2
        System.out.println(person1); // The name attribute of the Address object in person1 is also modified
        System.out.println(person2);
        System.out.println(person1 == person2); // Judge whether the object from the clone is the same as the original object
    }
}

The results are as follows:

It can be seen that when the attribute of an object is a basic type, a copy will be directly copied to the new object. If it is a reference type, the address of the reference type will be copied to the new object. Changing the value of the referenced object quoted by a reference type is equivalent to changing the two objects together.

Deep cloning

   deep clone: if it is a basic data type, copy it directly to the cloned object; if it is a reference type, copy the referenced object to the cloned object.

package clone.bean;

public class Person implements Cloneable{
    private int age;
    private String name;
    private Address address;
 	
 	//setter and getter are omitted 
 
    @Override
    public  Person clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone(); // clone object first
        person.address = (Address) address.clone(); // Deep clone: clone a copy of the referenced object
        return person;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}
public class DeepCloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person(); // person1 object
        person1.setAge(22);
        person1.setName("Zhang San");
        Address address = new Address("Beijing"); // reference type
        person1.setAddress(address);
        Person person2 = person1.clone();
        person2.getAddress().setName("Nanjing"); // Modify the name attribute of the Address object in person2
        System.out.println(person1); // Beijing
        System.out.println(person2); // Nanjing
        System.out.println(person1 == person2);
    }
}

The results are as follows:

Deep cloning is successful, but if there are too many object reference types, rewriting the method becomes troublesome. Then you can use serialization to implement deep cloning and save the object in the stream.

public class DeepCloneTest2 {

    public static void main(String[] args) throws Exception {
        Person p1 = new Person();
        p1.setAge(22);
        p1.setName("Zhang San");
        Address address = new Address("Zhejiang");
        p1.setAddress(address);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos); // Read object into stream
        oos.writeObject(p1); // Write object
        ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());//Converts the data in the output stream to a byte array
        ObjectInputStream ois = new ObjectInputStream(bais);// read
        Person o = (Person) ois.readObject();
        System.out.println(o);
        Person p2 = p1.clone();
        p2.getAddress().setName("Shaanxi");
        System.out.println(p2);
        ois.close();
        bos.close();
    }
    
}

Keywords: Java object clone

Added by PRSBOY on Fri, 14 Jan 2022 10:24:12 +0200