Monday, July 19, 2010

Shallow Copy and Deep CopyTest in Cloning

/*
Java provides a mechanism for creating copies of objects called cloning. There are two ways to make a copy of an object called shallow copy and deep 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 references are copied. Thus, if the object you are copying contains references to yet other objects, a shallow copy refers to the same subobjects.
Deep copy is a complete duplicate copy of an object. If an object has references to other objects, complete new copies of those objects are also made. A deep copy generates a copy not only of the primitive values of the original object, but copies of all subobjects as well, all the way to the bottom. If you need a true, complete copy of the original object, then you will need to implement a full deep copy for the object.
Java supports shallow and deep copy with the Cloneable interface to create copies of objects. To make a clone of a Java object, you declare that an object implements Cloneable, and then provide an override of the clone method of the standard Java Object base class. Implementing Cloneable tells the java compiler that your object is Cloneable. The cloning is actually done by the clone method.*/


package com.shallow;

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 clone() {
//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 ShallowCopyTest {

/**
* @param args
*/
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.clone();

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());

}

}
--------------------------------------------------
package com.deep;

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 clone() {
/*//Deep copy
Person p = new Person(name, car.getName());

return p;*/
try {
Person copy = (Person)super.clone();
copy.car = (Car)car.clone();
return copy;
} catch (CloneNotSupportedException e) {
throw new Error("This should not occur since we implement Cloneable");
}


}
}

class Car implements Cloneable{

private String name;

public String getName() {
return name;
}

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

public Car(String s) {
name = s;
}

@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}

public class DeepCopyTest {

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.clone();

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());

}
}
---------------------------------

//from web site

Shallow Copy Test


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 clone() {
//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 ShallowCopyTest {

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.clone();

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());

}
}

//
in shallow copy , the obj having ref var of any other class, then if u try to change the value of that ref var value in cloned obj of original obj, we can find changed value in ref var.but other instance var values will remain same.

it means , in shallow cpoy,
change in clone obj may effect the ref variable which r there in the original obj.
out put
--------
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


//----------------------------------------------------------------


Deep Copy Test

/*
Correct Output:
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

*/

/*
Software Architecture Design Patterns in Java
by Partha Kuchana

Auerbach Publications

*/



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 clone() {
//Deep copy
Person p = new Person(name, car.getName());
return p;
}
}

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 DeepCopyTest {

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.clone();

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());

}
}

No comments: