Deep vs Shallow Copy

package com.test;
public class User implements Cloneable{
private String name;
private Integer age;
private Address address;

public User(String name, Integer age, Address address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
@Override
public Object clone() throws CloneNotSupportedException{
return super.clone();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public static void main(String[] args) {
Address add=new Address(“243″,”Ghaziabad road”,”Gujarat”);
User user=new User(“sunita”,50,add);
User userClone=null;
try {
userClone=(User)user.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(“Original user address–“+user.getAddress());
System.out.println(“Cloned user address–“+userClone.getAddress());

}
}

Output for above sysouts:
Original user address–com.test.Address@15db9742
Cloned user address–com.test.Address@15db9742

As you can see above in a shallow copy, userclone creates a copy of name and age primitive attributes, however for address it reuses the same address object for userclone. So, now the clone object has a copy of primitive values but the object references refer to the same objects as the original copy.

Shallow Copies have a significant drawback. As we saw above, cloned object and original copy refer to the same address object. Any change that cloned object makes in address object will also be reflected in original copy, which is an unwanted behaviour. What we really wanted is two separate copies of user object. Deep copying comes to our rescue for this kind of situation.

Deep copying not just clones the primitive values, it also creates copies of object references.

user and userClone have their own instances of empAddress. Any change done to user’s address will not have any affect on userClone’s address and vice-a-versa.

To implement deep copying – User will still need to implement Cloneable, and it will still override Object.clone() method. But inside the overridden clone() method, instead of calling super.clone(), a clone of an User object is constructed step-by-step using custom code as shown in the code below –

@Override
public Object clone() throws CloneNotSupportedException {
User userClone = (User) super.clone();
Address addressClone = new Address(this.address.getHouseNo(),
this.address.getStreet(),
this.address.getCity());
userClone.address(addressClone);
return userClone;
}

Advertisements