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
Cloneable
interface 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.
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();
}
}
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();
}
}
}
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