- The process of creating exactly duplicate object is called Cloning.
- The main purpose of cloning is to maintain backup copy and to preserve state of an object.
- We can perform cloning by using clone method of object class.
- clone() method is present in Object class
Syntax :
protected native Object clone() throws CloneNotSupportedException; - Note : The default cloning provided by object class’s method is called shallow cloning. i.e if we clone an object which contains a object in it then that object is not cloned instead the cloned object point to the same sub object.
- Small example at the bottom of the page
Demo Program of Cloning :
package com.clonable.demo1; public class ClonableDemo { public static void main(String[] args) throws CloneNotSupportedException { Demo demoObj1 = new Demo(); demoObj1.setX(10); demoObj1.setY(20); Demo demoObj2 = demoObj1; System.out.println("Initial Object : "+demoObj1); demoObj2.setX(30); System.out.println("Value is changes due to use of reference : "+demoObj1); Demo demoObj3 = (Demo)demoObj1.clone(); demoObj3.setX(3333); demoObj3.setY(3333); System.out.println("Value does not change due to use of clone : "+demoObj1); System.out.println("Printing Cloned Object : "+demoObj3); } } class Demo implements Cloneable { int x; int y; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public String toString(){ return "X : " +x+ " Y : "+y; } public Object clone() throws CloneNotSupportedException { return super.clone(); } }
Points to remember while writing the above code :
- clone() method is present in Object class and not in Cloneable Interface
- clone() method is a protected method hence you may have to override the method to make it visible
- clone() method returns an Object and we need to type cast it to our required method
- Clonable Interface is a marker interface and it does not contain any methods.
- Clonable Interface needs to be implemented to a class to call the clone() method on its object else may result into a runtime exception.
Shallow Cloning :
- The process of creating bit wise copy of an object is called shallow cloning.
- If the main object contain primitive variables then exactly duplicate copies will be created in the cloned object.
- If the main object contain any reference variable then corresponding object wont be created just duplicate reference variable will be created pointing to old contained object
- Object class clone method is meant for shallow cloning.
- In shallow cloning by using cloned object reference if we perform any change to the contained object then those changes will be reflected to the main object.
- To overcome this problem we should go for deep cloning.
- If object contains only primitive variables then we should go for Shallow Cloning.
package com.cloneable.demo3; public class DemoShallowCloning { public static void main(String[] args) throws CloneNotSupportedException { Person tyson = new Person(new Employee(1000),10); System.out.println("Tyson Object : "+tyson); Person justin = (Person)tyson.clone(); justin.e.salary=2000; justin.age=12; System.out.println("Tyson Object's Salary changes even after clone since shallow clone : "+tyson); } } class Employee{ public int salary; Employee(int salary){ this.salary = salary; } } class Person implements Cloneable{ public int age; public Employee e; Person(Employee e, int age){ this.e = e; this.age = age; } public Object clone() throws CloneNotSupportedException { return super.clone(); } public String toString() { return "Salary : "+e.salary+" Age : "+age; } }
Deep Cloning :
- The process of creating exactly duplicate independent copy including contained object is called deep cloning.
- In deep cloning if the main object contain any primitive variables then in the cloned object duplicates copies will be created.
- If the parent object contains any reference variable then the corresponding contained objects will be created in the cloned copy.
- By default object class clone method meant for shallow cloning but we can implement deep cloning explicitly by overriding clone method in our class.
- By using cloned object reference if we perform any change to the contained object then those changes won’t be reflected to the main object.
- If object contains reference variables then we should go for deep cloning
package com.cloneable.demo2; public class DemoShallowCloning { public static void main(String[] args) throws CloneNotSupportedException { Person tyson = new Person(new Employee(1000),10); System.out.println("Tyson Object : "+tyson); Person justin = (Person)tyson.clone(); justin.e.salary=2000; justin.age=12; System.out.println("Tyson Object's Salary remains same after clone since deep cloning : "+tyson); } } class Employee{ public int salary; Employee(int salary){ this.salary = salary; } } class Person implements Cloneable{ public int age; public Employee e; Person(Employee e, int age){ this.e = e; this.age = age; } public Object clone() throws CloneNotSupportedException { return new Person(new Employee(this.e.salary),this.age); } public String toString() { return "Salary : "+e.salary+" Age : "+age; } }
Very small Example :
public class CloneDemo extends Object implements Cloneable{ public static void main(String[] args) throws CloneNotSupportedException { System.out.println("Hello"); CloneDemo c1 = new CloneDemo(); CloneDemo c2 = (CloneDemo) c1.clone(); } protected Object clone() throws CloneNotSupportedException { return super.clone(); } }