Deep Copy or Shallow Copy in Java – How to choose?

Deep_shallow_copy

Deep copy and shallow copy

Overview: In this article we will discuss the process of copying objects in java. The purpose of copying can be different based on the application requirement. But there are mainly two types of copying available, deep and shallow copy. The method of copying varies in these two approaches.

Introduction:
The action of copying the attributes of one object into another of same data type is called object copy. In java, we have the following approaches of copying one object into another

  • Shallow Copy: Here if the field which is to be copied is a primitive type, then the value is copied else if the field which is to be copied is a memory address (or an object itself) then the address is copied. Thus if the address is changed by one object, the change gets reflected everywhere.
  • Deep Copy: Here the data is copied in both the situations. This approach is costlier and slower.
  • Lazy Copy: This is a combination of the above two approaches. Initially the shallow copy approach is used and then checked if the data is shared by many objects and the program needs to modify an object, the deep copy approach is used.

So we can select the type of copying based on the following two conditions

  • Use shallow copying when no encapsulation is required.
  • Use deep copying when encapsulation is required.

Shallow Copy:

In shallow copy, a new object is created which contains the exact copy of the values in the original object. Shallow copy follows the bit-wise copy approach. In shallow copy if the field is a memory address, then the address is copied. Thus if the address is changed by one object, the change gets reflected everywhere.

Shallow copy

Shallow copy

Figure 1: The flow chart describes shallow copy

In this figure, the object – mainObj1 has a field named as field1 of a primitive type say int, and an object of type String When we do a shallow copy of mainObj1, mainObj2 is created with field2 of type int which contains the copied value of field1 but the String object in mainObj2 – still points to objStr itself. Since field1 is a primitive data type, the value of it is copied into field2. But since objStr is an object, mainObj2 is pointing to the same address of objStr. So any changes made to objStr via mainObj1 get reflected in mainObj2.

Implementation:

[code]

Listing 1: Class SubjectVO.java describes value object for subjects

package com.home.objectCopy;

public class SubjectVO {

private String name;

/**

* @return the name

*/

public String getName() {

return name;

}

/**

* @param name

* the name to set

*/

public void setName(String name) {

this.name = name;

}

public SubjectVO(String name) {

this.name = name;

}

}

[/code]

Listing 2: Class PupilVO.java describing value object for pupil

[code]

package com.home.objectCopy;

public class PupilVO implements Cloneable {

// Contained object

private SubjectVO subj;

private String name;

/**

* @return the subj

*/

public SubjectVO getSubj() {

return subj;

}

/**

* @param subj

* the subj to set

*/

public void setSubj(SubjectVO subj) {

this.subj = subj;

}

/**

* @return the name

*/

public String getName() {

return name;

}

/**

* @param name

* the name to set

*/

public void setName(String name) {

this.name = name;

}

public PupilVO(String name, String sub) {

this.name = name;

this.subj = new SubjectVO(sub);

}

public Object clone() {

// shallow copy

try {

return super.clone();

} catch (CloneNotSupportedException e) {

return null;

}

}

}

[/code]

Listing3: Class ShallowCopyTest.java describing copy process

[code]
package com.home.objectCopy;

public class ShallowCopyTest {

public static void main(String[] args) {

// Original Object

PupilVO stud = new PupilVO(“Johnathan”, “Algebra”);

System.out.println(“Original Object: ” + stud.getName() + ” – ”

+ stud.getSubj().getName());

// Clone Object

PupilVO clonedStud = (PupilVO) stud.clone();

System.out.println(“Cloned Object: ” + clonedStud.getName() + ” – ”

+ clonedStud.getSubj().getName());

stud.setName(“Daniel”);

stud.getSubj().setName(“Physics”);

System.out.println(“Original Object after it is updated: ”

+ stud.getName() + ” – ” + stud.getSubj().getName());

System.out.println(“Cloned Object after updating original object: ”

+ clonedStud.getName() + ” – ”

+ clonedStud.getSubj().getName());

}

}

[/code]

Output: The output of this program is as under

Original Object: Johnathan – Algebra

Cloned Object: Johnathan – Algebra

Original Object after it is updated: Daniel – Physics

Cloned Object after updating original object: Johnathan – Physics

Here we see that the value of the field name gets changed after the copy operation but the value of the object subject remains the same as it is pointing to the same memory address. Hence the subject for Jonathan becomes ‘Physics’ where as it should be ‘Algebra’ as the object for SubjectVO in the cloned object remains unchanged.

Deep Copy:

In deep copy, not only all the fields of an object are copied, all the dynamically allocated memory address which is pointed by that object is also copied.

Deep Cpoy

Deep Copy

Figure 2: The diagram describes deep copy process

In this figure, the object mainObj1 has fields field1 a primitive data type say int, and an object of type String When we do a deep copy of mainObj1, mainObj2 is created with field2 containing the copied value of field1 and objStr2 is created which contains the copied value of objStr1 So any changes made to objStr1 in mainObj1 will not reflect in mainObj2.

Implementation:

Listing4: Class describing deep copy

[Code]

package com.home.DeepCopy;

public class PupilVO implements Cloneable {

// Contained object

private SubjectVO subj;

private String name;

/**

* @return the subj

*/

public SubjectVO getSubj() {

return subj;

}

/**

* @param subj

* the subj to set

*/

public void setSubj(SubjectVO subj) {

this.subj = subj;

}

/**

* @return the name

*/

public String getName() {

return name;

}

/**

* @param name

* the name to set

*/

public void setName(String name) {

this.name = name;

}

public PupilVO(String name, String sub) {

this.name = name;

this.subj = new SubjectVO(sub);

}

public Object clone() {

// deep copy

PupilVO pupil = new PupilVO(name, subj.getName());

return pupil;

}

}

[/code]

The only difference between this approach and the earlier approach is that the clone method in the PupilVO returns a newly created PupilVO object. This ensures that whenever the copy mechanism in initiated, the object SubjectVO also gets changed. Deep copy has an alternative approach – serialization. In serialization, the whole object graph is written into a persistent store and read back when required. So whenever we read the object from the persistent store, the original object is referred.

Usage of shallow copy and deep copy:

There is no hard and fast rule defined for selecting between shallow copy and deep copy but normally we should keep in mind that if an object has only primitive fields, then obviously we should go for shallow copy, but if the object has references to other objects, then based on the requirement, shallow copy or deep copy should be done. If the references are not updated then there is no point to initiate a deep copy.

Explain lazy copy:

A lazy copy can be defined as a combination of both shallow copy and deep copy. The mechanism follows a simple approach – at the initial state, shallow copy approach is used. A counter is also used to keep a track on how many objects share the data. When the program wants to modify the original object, it checks whether the object is shared or not. If the object is shared, then the deep copy mechanism is initiated.

Summary:

In shallow copy, only fields of primitive data type are copied while the objects references are not copied. Deep copy involves the copy of primitive data type as well as objet references. There is no hard and fast rule as to when to do shallow copy and when to do a deep copy. Lazy copy is a combination of both of these approaches.

Tagged on:
============================================= ============================================== Buy best TechAlpine Books on Amazon
============================================== ---------------------------------------------------------------- electrician ct chestnutelectric
error

Enjoy this blog? Please spread the word :)

Follow by Email
LinkedIn
LinkedIn
Share