Cloning in JAVA
Cloning is a way to create exact copy of the object. It creates a new instance of object with all fields from the original object, and there is no operator for copying an object in JAVA — the assignment operator duplicates the reference, not the object. The clone() method provides the missing functionality.
By default java cloning is ‘field by field copy’ or shallow copy of object.
Java Cloneable Interface and clone() method-
1- You must implement Cloneable interface
2- you must override clone() method from object class.
protected Object clone() throws CloneNotSupportedException
The class Object
does not itself implement the interface Cloneable
, so calling the clone
method on an object whose class is Object
will result in throwing an exception at run time.
Code Example of Cloning —
class CloneTesting implements Cloneable {
int objectId;
String objectName;
CloneTesting(int id, String name) {
this.objectId = id;
this.objectName = name;
}
@Override
protected Object clone() throws CloneNotSupportedException
{
return super.clone();
}public static void main(String[] args) {try {CloneTesting object = new CloneTesting(1, "Object A");CloneTesting clonedObject = (CloneTesting) object.clone();CloneTesting referenceObject = object;// object and referenceObject are pointing to same objectSystem.out.println("Reference equality : " + (object.equals(referenceObject)));// object and referenceObject are pointing to same object (compared by hashCode() method)System.out.println("Hashcode of Original Object : " + object.hashCode());System.out.println("Hashcode of referenced Object : " + referenceObject.hashCode());System.out.println("Assigning object equality test result : " + (object.hashCode() == referenceObject.hashCode()));System.out.println("-----------------Cloning---------------------");// object and clonedObject are two different object (created by java cloning)System.out.println("Hashcode of Original Object : " + object.hashCode());System.out.println("Hashcode of cloned Object : " + clonedObject.hashCode());System.out.println("Cloned object equality test result : " + (object.hashCode() == clonedObject.hashCode()));} catch (CloneNotSupportedException e) {e.printStackTrace();}}}
Output —
Reference equality : true
Hashcode of Original Object : 1829164700
Hashcode of referenced Object : 1829164700
Assigning object equality test result : true
-----------------Cloning---------------------
Hashcode of Original Object : 1829164700
Hashcode of cloned Object : 2018699554
Cloned object equality test result : false
Types of Cloning —
1- Shallow Copy (default in JAVA)
2- Deep Copy
Shallow Copy-
Shallow clone is default implementation of JAVA. If you’re not cloning all the object types, then you’re making a shallow copy of the object. In this above example we’ve created a shallow copy of object.
class Mercedes implements Cloneable {String model;Owner owner;public Mercedes(String model, Owner owner) {this.model = model;this.owner = owner;}/*** @return the model*/public String getModel() {return model;}/*** @return the owner*/public Owner getOwner() {return owner;}
/*** @param owner the owner to set*/public void setOwner(Owner owner) {this.owner = owner;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public static void main(String[] args) {Owner owner = new Owner("ABC");Mercedes mercedes1 = new Mercedes("Benz", owner);// Now we will create clone of this objecttry {Mercedes mercedes2 = (Mercedes) mercedes1.clone();// mercedes1 and mercedes2 are now two different objectSystem.out.println("Mercedes1 Object Owner Name : " + mercedes1.getOwner().getName());System.out.println("Mercedes2 Object Owner Name : " + mercedes2.getOwner().getName());/** But now if we change the owner name in first object, it would be reflected in* second object also because its a shallow copy and it will just have reference* of object not new object itself.*/mercedes1.getOwner().setName("Updated Name");
System.out.println("Names after update in owner of first object.");
System.out.println("Mercedes1 Object Owner Name : " + mercedes1.getOwner().getName());System.out.println("Mercedes2 Object Owner Name : " + mercedes2.getOwner().getName());} catch (CloneNotSupportedException e) {e.printStackTrace();}}}Owner.javapublic class Owner {private String name;public Owner(String owner) {this.name = owner;}/*** @return the name*/public String getName() {return name;}/*** @param name the name to set*/public void setName(String name) {this.name = name;}}
Output —
Mercedes1 Object Owner Name : ABC
Mercedes2 Object Owner Name : ABC
Names after update in owner of first object.
Mercedes1 Object Owner Name : Updated Name
Mercedes2 Object Owner Name : Updated Name
Deep Copy —
In deep copy, we create a clone which is independent of object and making changes in cloned object should not affect original object.
@Overrideprotected Object clone() throws CloneNotSupportedException {Mercedes cloned = (Mercedes) super.clone();cloned.setOwner((Owner) cloned.getOwner().clone());return cloned;}Owner.java Implement Cloneable @Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
In this way we can achieve deep copy of objects.
There are third party libraries available which you can use for deep cloning ex- Apache Commons , SerializationUtils
No constructor is called on the object being cloned.
Feel free to drop comments if you have any questions on this article.
Keep Learning!!!