Sunday, 21 April 2013

What is Cloning?

                                                                                Cloning

Cloning refers to create duplicate copies of objects in java. Cloning of objects can be very useful if we use the prototype pattern. The clone( ) method generates a duplicate copy of the object on which it is called. Only classes that implement the Cloneable interface can be cloned. 

java.lang.cloneable : - Note that this interface does not contain the clone method. The Cloneableinterface doesn't have any members. It is an empty interface, used only to indicate cloning is supported by a class. Java supports two type of cloning: -  Shallow and Deep cloning. By default shallow copy is used in Java. Object class has a method clone() which does shallow cloning.

Shallow Copy:- Shallow clone only copies the top level structure of the object not the lower levels.
It is an exact bit copy of all the attributes. 
 

 
Shallow Cloning

In above figure, OriginalObject1 have fields "attributes1" of int type, and "ContainObject1" of Object type. After shallow copy of OriginalObject1, OriginalObject2 is created with "attributes2" containing the copied value of "attributes1" and still pointing to same object i.e ContainObject1. Since attributes1 is of primitive data type, the values of it are copied to attributes2 but ContainedObject1 is an object, so OriginalObject2 is still pointing to ContainObject1. If any changes made to ContainObject1 in OriginalObject1 will also reflect in OriginalObject2.

Deep Copy:- 

Using deep copy the object is copied along with the objects it refers to. Deep clone copies all the levels of the object from top to the bottom recursively.
Deep Cloning

 
In above figure, the OriginalObject1 have fields "attributes1" of int type, and "ContainObject1" of Object type. When we use deep copy of OriginalObject1, OriginalObject2is created with "attributes2" containing the copied value of "attributes1" and "ContainObject2" containing the copied value of ContainObject1.If any changes made to ContainObject1 in OriginalObject1 will not reflect in OriginalObject2.

Demo example of using Shallow Cloning:-

package com.gaurav.cloning;

class Student{
    public int studAge;
    public String studName;
   
    public Student(int age,String name){
        this.studAge = age;
        this.studName = name;
    }
   
    public Object Clone() throws CloneNotSupportedException{
        return this;
    }
    public String toString(){
        return "Student name is "+studName+" & Age is "+studAge;
    }
}
public class ShallowCloneDemo  {
    public ShallowCloneDemo() throws CloneNotSupportedException{
        Student std1 = new Student(32,"Gaurav");
        Student std2 = (Student)std1.Clone();
        System.out.println("The Cloned object before change-"+std2);
        std2.studAge = 25;
        std2.studName = "Aryan";
        System.out.println("The Cloned object after change-"+std2);
        System.out.println("The Original Object is-"+std1);
    }
    @SuppressWarnings("unused")
    public static void main(String args[]) throws CloneNotSupportedException{
        ShallowCloneDemo swt = new ShallowCloneDemo();
    }
}

Demo example of using Deep Cloning:-

package com.gaurav.cloning;

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

class PrimeMinister implements Cloneable, Serializable {

    private static final long serialVersionUID = 3055437071638880530L;
    public String name;
    public String memberParty;

    public PrimeMinister(String strName, String strParty) {
        this.name = strName;
        this.memberParty = strParty;
    }

    public Object Clone() throws CloneNotSupportedException {
        try {
            ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutput);
            oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(
                    byteArrayOutput.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    public String toString() {
        return "PrimeMinister name is " + name + " and he belogs to "
                + memberParty + " party";
    }
}

public class DeepCloningDemo {
    public static void main(String args[]) {
        try {

            PrimeMinister m = new PrimeMinister("Manmohan Singh", "Congress");
            System.out.println("Original Object Value -" + m);
            PrimeMinister m1 = (PrimeMinister) m.Clone();
            m1.name = "Atal Bihari Bajpai";
            m1.memberParty = "BJP";
            System.out.println("Cloned Object Value-" + m1);
            System.out.println("Original Object Value -" + m);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Note:- Using Serialization, we can achieve Deep cloning.

Disadvantage of Deep cloning :-
  • Serialization is costlier than object.clone() i.e.Shallow cloning.
  • It is difficult to achieve deep cloning using serialization because we have to write a lot of codes.
  • All objects are not serialized like transient.
Note:- Cloning library is also available for doing deep-cloning. It’s an open source and small library used for deep-cloning the objects. This library is licensed by Apache. The library doesn't clone jdk's immutable objects, Like String.


No comments:

Post a Comment