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.
- 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.Figure 1: The flow chart describes shallow copy
In this figure, the object - mainObj1 has fields 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:
Listing 1: Class SubjectVO.java describes value object for subjectspackage 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; } }
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; } } }
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()); } }
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 are pointed by that object are also copied.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:
Listing 4: Class describing deep copypackage 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; } }
So whenever we read the object from the persistent store, the original object is referred.
No comments:
Post a Comment