In this post we’ll see what are shallow copy and deep copy in Java with respect to Java object cloning and what are the differences between shallow copy and deep copy in Java.
Object cloning in Java
Object cloning is the process of creating an exact copy of the existing object. When you clone an object you get a new instance with the same content for the fields in the new object as in existing object.
Object cloning in Java is done using clone() method which is defined in java.lang.Object class. Only those object that implement Cloneable interface are eligible for cloning.
Both shallow copy and deep copy relates to how object is cloned. When object cloning is done using the default clone method (by calling the clone method of the Object class) it returns a shallow copy of the object.
For creating a deep copy of an object you would need to override the clone method.
Shallow copy in Java
As already stated when you use default clone()
method, shallow copy of the object is created. What it means is that there would be field-to-field assignment. New object will also have the same fields as the original object and the same content
for the fields too. It works fine for primitive data types but in case there is another object reference in your class it may
be a problem.
If a class whose object is cloned contains another object then field-to-field assignment will be done for the contained object too in the cloning process. Since Java is pass by value, so copying the value of the object means object reference would be copied and there lies the problem.
Reference of the contained object is shared between the original object and the cloned object and making any change to that object in the cloned object would be reflected in the original object too and vice versa is also true.
For example suppose there is a class ClassB which has another object objA of Class A.public class ClassB implements Cloneable{ private ClassA objA; ... ... }
When object of ClassB is cloned, objA reference is shared between the original object and the cloned object.
Shallow copy Java example
Here we have a Class called ClassA with 2 int fields. Another class ClassB which has a ClassA object and an int field.
Then you create an object objB of ClassB and clone it to get a new object objB2. In both of these objects, reference of ClassA object will be shared.
ClassA
public class ClassA implements Cloneable{ private int i; private int j; // Constructor public ClassA(int i, int j){ this.i = i; this.j = j; } public void setI(int i) { this.i = i; } public void setJ(int j) { this.j = j; } public int getI() { return i; } public int getJ() { return j; } }
ClassB
public class ClassB implements Cloneable{ private int x; private ClassA objA; public ClassB(int x, ClassA objA){ this.x = x; this.objA = objA; } public Object clone() throws CloneNotSupportedException{ return super.clone(); } public int getX() { return x; } public ClassA getObjA() { return objA; } public void setX(int x) { this.x = x; } public void setObjA(ClassA objA) { this.objA = objA; } }
CloningDemo class
public class CloningDemo { public static void main(String[] args) { ClassB objB = new ClassB(10, new ClassA(20, 30)); ClassB objB2 = null; try { objB2 = (ClassB)objB.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // value of field i of objA changed // in cloned object objB2.getObjA().setI(100); // Value of primitive field x changed // in cloned object objB2.setX(1); System.out.println("objB.x- " + objB.getX() + " objB.objA.i- " + objB.getObjA().getI() + " objB.objA.j- " + objB.getObjA().getJ()); System.out.println("objB2.x- " + objB2.getX() + " objB2.objA.i- " + objB2.getObjA().getI() + " objB2.objA.j- " + objB2.getObjA().getJ()); } }
Output
objB.x- 10 objB.objA.i- 100 objB.objA.j- 30 objB2.x- 1 objB2.objA.i- 100 objB2.objA.j- 30
In CloningDemo class objB is cloned to get a new instance objB2. Value of primitive field x is changed in the cloned object objB2, you can see that both objects have their own independent values for field x.
Coming to object field, objB2 will have its own field objA where value of field i is changed. You can see that value in the original object objB for objA.i is also changed as the objA reference is shared between the objects. That’s one drawback of shallow copy.
Deep Copy in Java
When a deep copy is done objects referenced by the cloned object are distinct from those referenced by original object, and independent.
To create a deep copy while cloning an object you need to override clone method and call clone() method for even the objects referenced by the cloned object.
Deep copies are more expensive, as you need to create additional objects, and can be substantially more complicated, due to references possibly forming a complicated graph.
Deep copy Java example
Here we have a Class called ClassA with 2 int fields. Another class ClassB which has a ClassA object and an int field.
In classB, clone() method is overridden and clone method is explicitly called for the reference object objA too to get a separate copy of referenced object too.
class ClassA implements Cloneable{ private int i; private int j; // Constructor public ClassA(int i, int j){ this.i = i; this.j = j; } public void setI(int i) { this.i = i; } public void setJ(int j) { this.j = j; } public int getI() { return i; } public int getJ() { return j; } public Object clone() throws CloneNotSupportedException{ return super.clone(); } } class ClassB implements Cloneable{ private int x; private ClassA objA; public ClassB(int x, ClassA objA){ this.x = x; this.objA = objA; } public Object clone() throws CloneNotSupportedException{ ClassB obj = (ClassB) super.clone(); // explicitly cloning classA object too obj.objA = (ClassA) objA.clone(); return obj; } public int getX() { return x; } public ClassA getObjA() { return objA; } public void setX(int x) { this.x = x; } public void setObjA(ClassA objA) { this.objA = objA; } } public class CloningDemo { public static void main(String[] args) { ClassB objB = new ClassB(10, new ClassA(20, 30)); ClassB objB2 = null; try { objB2 = (ClassB)objB.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // value of field i of objA changed // in cloned object objB2.getObjA().setI(100); // Value of primitive field x changed // in cloned object objB2.setX(1); System.out.println("objB.x- " + objB.getX() + " objB.objA.i- " + objB.getObjA().getI() + " objB.objA.j- " + objB.getObjA().getJ()); System.out.println("objB2.x- " + objB2.getX() + " objB2.objA.i- " + objB2.getObjA().getI() + " objB2.objA.j- " + objB2.getObjA().getJ()); } }
Output
objB.x- 10 objB.objA.i- 20 objB.objA.j- 30 objB2.x- 1 objB2.objA.i- 100 objB2.objA.j- 30
Now the change to objA.i field in the cloned object is not reflected to the original object.
Shallow copy Vs Deep Copy in Java
- In case of shallow copy, primitive fields are created separately for the cloned object but any object reference is shared
between the original and cloned object.
In case of deep copy, separate copies of the referenced objects are also created so that original and cloned object are completely independent of each other. - If class has only primitive fields shallow copy is the best choice.
If class contains other objects then you need deep copy to have separate copies for the contained objects. - Object cloning done by using Object class’ clone() method by default creates a shallow copy of an object.
For creating a deep copy of any object you need to override the clone() method and provide the functionality to create separate copies of the reference objects too. - Shallow copies are simple to implement and typically cheap, as they can be usually implemented by simply copying the bits exactly.
Deep copies are expensive and more complicated because you may have to create a whole object graph for the cloned object.
That's all for this topic Shallow Copy And Deep Copy in Java Object Cloning. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Java Basics Tutorial Page
Related Topics
You may also like-
Thank you so much for the detailed article
ReplyDelete