Java clone shallow, deep cloning

Shallow clone

Copy only the basic data types and data type String and the corresponding array type, other types of reference data just copied the reference address;

Use

Implement the Cloneable interface and override the clone method, call super.clone () can

public static class Person implements Cloneable {
    @Override
    protected Person clone() throws CloneNotSupportedException {
         return (Person) super.clone();
    }
}

E.g

public static class Person implements Cloneable {
    public String name;
    public int age;
    public String[] names;
    public Baby baby;
    public ArrayList<String> names2 = new ArrayList<>();
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age + ", names=" + Arrays.toString(names) + ", baby=" + baby + ", names2=" + names2 + '}';
    }
    @Override
    protected Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
}
public static class Baby implements Cloneable {
    public String name;
    public int age;
    public String[] names;
    public Baby(String name, int age, String[] names) {
        this.name = name;
        this.age = age;
        this.names = names;
    }
    @Override
    public String toString() {
        return "Baby{" + "name='" + name + '\'' + ", age=" + age + ", names=" + Arrays.toString(names) + '}';
    }
    @Override
    protected Baby clone() throws CloneNotSupportedException {
        return (Baby) super.clone();
    }
}
public static void main(String[] args) throws CloneNotSupportedException {
    Person person = new Person("person", 10);
    person.names = new String[]{"qq", "www"};
    person.baby = new Baby("baby", 20, new String[]{"qqqqq", "wwwww"});
    person.names2.add("1111");
    person.names2.add("2222");
    //  对克隆后的数据进行更改
    Person clone = person.clone();
    clone.name = "person1";
    clone.age = 23;
    clone.names2.add("3333");
    clone.names = new String[]{"111", "222"};

    clone.baby.name = "baby1";
    clone.baby.names = new String[]{"ttttt"};
    
    System.out.println(person.toString());
    System.out.println(clone.toString());
}

The corresponding output

Person{name='person', age=10, names=[qq, www], baby=Baby{name='baby1', age=20, names=[ttttt]}, names2=[1111, 2222, 3333]}
Person{name='person1', age=23, names=[111, 222], baby=Baby{name='baby1', age=20, names=[ttttt]}, names2=[1111, 2222, 3333]}

in conclusion

We found that changes to the data in the data to the cloned after:

  • Basic data types, String, String primitive data types and the corresponding array copy is made, the change does not affect the original data;
  • Reference data type, just copy the reference address, the data type of the operation of the reference clones, also become raw data, such as Baby test subject;

Deep clone

Create a new type of reference data object and attribute cloning in the past; recursively clone reference data types;

Method to realize

public static class Person implements Cloneable {
    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();
        person.baby = baby.clone();
        person.names2 = (ArrayList<String>) names2.clone();
        return person;
    }
}

E.g

Examples of the clone method of the above-shallow clone into

public static class Person implements Cloneable {
    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();
        person.baby = baby.clone();
        person.names2 = (ArrayList<String>) names2.clone();
        return person;
    }
}

Export

Person{name='person', age=10, names=[qq, www], baby=Baby{name='baby', age=20, names=[qqqqq, wwwww]}, names2=[1111, 2222]}
Person{name='person1', age=23, names=[111, 222], baby=Baby{name='baby1', age=20, names=[ttttt]}, names2=[1111, 2222, 3333]}

in conclusion

  • Reference data types to create a new data, the data clone of change, without affecting the original data;

note

1. You must implement the Cloneable interface, or call the clone method throws an exception

Implement the clone method of Object

protected Object clone() throws CloneNotSupportedException {
   if (!(this instanceof Cloneable)) {
       throw new CloneNotSupportedException("Class " + getClass().getName() +" doesn't implement Cloneable");
   }
   return internalClone();
}

 /*
 * Native helper method for cloning.
 */
@FastNative
private native Object internalClone();

2. Cloning of a subclass also deep clone replication method

Implements parent clone method, if the subclass does not override, then the subclass only shallow clone;

Reproduced in: https: //www.jianshu.com/p/afd772a2c6d0

Guess you like

Origin blog.csdn.net/weixin_34101229/article/details/91252593