Sunday, May 22, 2016

Cloning ,Shallow Copy and Deep copy

Ø  Instead of creating object using new operator which might involve lot of processing, database call. In java, object creation can also be achieved using clone() of Object class.
Ø  Interface Cloneable – Marker Interface
Ø  By implementing this interface we can make the duplicate copy of our object by calling clone() method of  java.lang.Object class.
Ø  By default any clone() method gives the shallow copy of the object i.e. if we invoke super.clone() then it’s a shallow copy but if we want to deep copy we have to override the clone() method and make it public and give own definition of making copy of object.

      What is Shallow Copy?
Shallow copy is a bit-wise copy of an object. A new object is created that has an exact copy of the values in the original object. If any of the fields of the object are references to other objects, just the reference addresses are copied i.e., only the memory address is copied.



           
Fig 1 -Shallow Copy of MainObject1
In this figure, the MainObject1 have fields "field1" of int type, and "ContainObject1" of ContainObject type. When you do a shallow copy of MainObject1, MainObject2 is created with "field3" containing the copied value of "field1" and still pointing to ContainObject1 itself. Observe here and you will find that since field1 is of primitive type, the values of it are copied to field3 but ContainedObject1 is an object, so MainObject2 is still pointing to ContainObject1. So any changes made to ContainObject1 in MainObject1 will reflect in MainObject2.

What is Deep Copy?
A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy occurs when an object is copied along with the objects to which it refers.

                      Fig 2- Deep copy of MainObject1
In this figure, the MainObject1 have fields "field1" of int type, and "ContainObject1" of ContainObject type. When you do a deep copy of MainObject1, MainObject2 is created with "field3" containing the copied value of "field1" and "ContainObject2" containing the copied value of ContainObject1.So any changes made to ContainObject1 in MainObject1 will not reflect in MainObject2.

package com.javadsalgo.cloning;

class Subject {
    
     private String name;

     public String getName() {
           return name;
     }

     public void setName(String s) {
           name = s;
     }

}

class Student implements Cloneable {
     private Subject subj;
     private String name;

     public Subject getSubj() {
           return subj;
     }

     public void setSubj(Subject subj) {
           this.subj = subj;
     }

     public String getName() {
           return name;
     }

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

     public Object clone() {
           // shallow copy
           try {
                return super.clone();
           } catch (CloneNotSupportedException e) {
                return null;
           }
     }

}

public class CopyTest {
     public static void main(String[] args) {
           Student student = new Student();
           Subject subj= new Subject();
           subj.setName("Java");
           student.setName("Paras");
           student.setSubj(subj);
           Student cloneStudent=(Student)student.clone();
           System.out.println("Original Object\t"+"Name ="+student.getName()+"\tSubject name ="+student.getSubj().getName());
           System.out.println("Cloned Object\t"+"Name ="+cloneStudent.getName()+"\tSubject name ="+cloneStudent.getSubj().getName());
           student.setName("Sonal");
           student.getSubj().setName("C++");
           student.setSubj(subj);
           System.out.println("Original Object after it is updated\t"+"Name ="+student.getName()+"\tSubject name ="+student.getSubj().getName());
           System.out.println("Cloned Object\t"+"Name ="+cloneStudent.getName()+"\tSubject name ="+cloneStudent.getSubj().getName());
     }
}

Output:
Original Object                 Name =Paras     Subject name =Java
Cloned Object                   Name =Paras     Subject name =Java
Original Object after it is updated  Name =Sonal     Subject name =C++
Cloned Object                   Name =Paras     Subject name =C++


If you observe, the changes made to "name" field of original object (Student class) is not reflected in cloned object but the changes made to "name" field of contained object (Subject class) is reflected in cloned object. This is because the cloned object carries the memory address of the Subject object but not the actual values. Hence any updates on the Subject object in Original object will reflect in Cloned object.

1 comment:

  1. https://stackoverflow.com/questions/64036/how-do-you-make-a-deep-copy-of-an-object-in-java

    ReplyDelete