CLONE and CLONEABLE:
Clone is a protected method defined in Object class. To clone any class that class should must implement Cloneable interface which is a marker interface otherwise it will through CloneNotSupportedException.
Cloneable is a marker interface so no method defined. Interesting thing is it does not support Generics probably because it was there before Generics or for backward compatibility.
Cloneable Vs Serialization:
Serialization is a process to convert your object into bitstream and send accross the network and deserialze at other end,process like Marshling. By default serialization dies Deep Copy.
SHALLOW COPY vs DEEP COPY:
Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure, not the elements. With a shallow copy, two collections now share the individual elements.
Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.
How to do SHALLOW COPY:
For shallow copy we can clone() method but make sure all field reference classes should also be Cloneable.
How to do DEEP COPY:
Solution 1: Use Copy Constructor
class DeepCloneableClass {//Define other constructor as usual
//Copy Constructor for deep cloning
public DeepCloneableClass(DeepCloneableClass from){
this.field1 = from.getField1();
...
...
}
}
Solution 2: Use Factory Pattern
class DeepCloneableClass {//Create factory method for deep cloning
public static DeepCloneableClass fromInstance(DeepCloneableClass from){
new DeepCloneableClass(from.getFeild1());
...
}
}
Solution 3: Force by new Interface like DeepCloneable
interface DeepCloneable<T>{
//In implementaion create deep copy
public T deepClone(T t);
}
Example Showing Difference Between Deep and Shallow Copy:
************************************************
package com.object;
class Person implements Cloneable {
// Lower-level object
private Car car;
private String name;
public Car getCar() {
return car;
}
public String getName() {
return name;
}
public void setName(String s) {
name = s;
}
public Person(String s, String t) {
name = s;
car = new Car(t);
}
public Object deepClone() {
// Deep copy
Person p = new Person(name, car.getName());
return p;
}
public Object shallowClone() {
// shallow copy
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
class Car {
private String name;
public String getName() {
return name;
}
public void setName(String s) {
name = s;
}
public Car(String s) {
name = s;
}
}
public class DeepNShallowCopyTest {
public static void main(String[] args) {
// Original Object
Person p = new Person("Person-A", "Civic");
System.out.println("Original (orginal values): " + p.getName() + " - "
+ p.getCar().getName());
// Clone as a shallow copy
Person q = (Person) p.shallowClone();
System.out.println("Clone (before change): " + q.getName() + " - "
+ q.getCar().getName());
// change the primitive member
q.setName("Person-B");
// change the lower-level object
q.getCar().setName("Accord");
System.out.println("Clone (after change): " + q.getName() + " - "
+ q.getCar().getName());
System.out.println("Original (after clone is modified): " + p.getName()
+ " - " + p.getCar().getName());
System.out.println("********************************");
// Original Object
Person dp = new Person("Person-A", "Civic");
System.out.println("Original (orginal values): " + dp.getName() + " - "
+ dp.getCar().getName());
// Clone as a shallow copy
Person dq = (Person) dp.deepClone();
System.out.println("Clone (before change): " + dq.getName() + " - "
+ dq.getCar().getName());
// change the primitive member
dq.setName("Person-B");
// change the lower-level object
dq.getCar().setName("Accord");
System.out.println("Clone (after change): " + dq.getName() + " - "
+ dq.getCar().getName());
System.out.println("Original (after clone is modified): "
+ dp.getName() + " - " + dp.getCar().getName());
}
}
OUTOUT :
Original (orginal values): Person-A - Civic
Clone (before change): Person-A - Civic
Clone (after change): Person-B - Accord
Original (after clone is modified): Person-A - Accord
********************************
Original (orginal values): Person-A - Civic
Clone (before change): Person-A - Civic
Clone (after change): Person-B - Accord
Original (after clone is modified): Person-A - Civic
No comments:
Post a Comment