Object Cloning in Java
A clone is an exact copy of
the original. In java, it essentially means the ability to create an object with
similar state as the original object. The clone() method provides
this functionality.
The java.lang.Cloneable
interface must be implemented by the class whose clone object wants to
create. If Cloneable interface is not
implemented, clone() method generates CloneNotSupportedException.
protected Object clone() throws CloneNotSupportedException
Facts about cloning
By default, java cloning is
‘field by field copy’ i.e. as the Object class does not
have idea about the structure of class on which clone() method
will be invoked. So, JVM when called for cloning, do following things:
1) If the class
has only primitive data type members then a completely
new copy of the object will be created and the reference to the new object copy will be returned.
2) If the class
contains members of any class type then only the object
references to those members are copied and hence the member references in both the original object as well as the
cloned object refer to the same object.
Facts behind cloning
1) You must implement Cloneable interface.
2) You must override clone() method
from Object class. [Its weird. clone() method should have been in Cloneable
interface.]
/*
Creates and returns a copy of this object. The precise meaning of
"copy" may depend on the class of the object.
The general intent is that, for any object x, the expression:
1) x.clone() != x will be true
2) x.clone().getClass() == x.getClass() will be true, but these are
not absolute requirements.
3) x.clone().equals(x) will be true, this is not an absolute
requirement.
*/
protected native Object
[More ...] clone() throws CloneNotSupportedException;
1. First
statement guarantees that cloned object will have separate memory
address assignment.
2. Second
statement suggests that original and
cloned objects should have same class type, but it is not mandatory.
3. Third
statement suggests that original and
cloned objects should have be equal using equals() method, but it is not
mandatory.
public class Employee implements Cloneable
{
private int empoyeeId;
private String employeeName;
private Department department;
public Employee(int id, String name, Department dept) {
this.empoyeeId = id;
this.employeeName = name;
this.department = dept;
}
/** Shallow copy. */
/*@Override
protected Object clone()
throws CloneNotSupportedException {
return super.clone();
}*/
/** Deep copy. */
@Override
protected Object
clone() throws CloneNotSupportedException {
Employee cloned = (Employee)super.clone();
cloned.setDepartment((Department)cloned.getDepartment().clone());
return cloned;
}
/** setters and getters. */
}
public class Department {
private int id;
private String name;
public Department(int id, String name) {
this.setId(id);
this.setName(name);
}
/** for deep copy. */
@Override
protected Object
clone() throws CloneNotSupportedException {
return super.clone();
}
/** setters and getters. */
}
public class TestCloning {
public static void main(String[] args) throws CloneNotSupportedException {
Department dept = new Department(1, "Human Resource");
Employee original = new Employee(1, "Admin", dept);
//Lets create a clone of original object
Employee cloned = (Employee) original.clone();
//Let verify using employee id, if cloning actually workded
System.out.println(cloned.getEmpoyeeId());
//Must be true and objects must have different memory addresses
System.out.println(original != cloned);
//As we are returning same class; so it should be true
System.out.println(original.getClass() == cloned.getClass());
//Default equals method checks for refernces so it
should be false.
If we
want to make it true.
//we need to override equals method in Employee class.
System.out.println(original.equals(cloned));
}
}
protected native Object clone() throws CloneNotSupportedException;
ReplyDeleteprotected method of Object class.
So it mandatory to Override it.
public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
CloneTest obj = new CloneTest();
CloneTest clonedObj = (CloneTest) obj.clone();
if(obj==clonedObj) {
System.out.println("equal");
} else {
System.out.println("cloned new instanse");
}
}
}
Exception:
Exception in thread "main" java.lang.CloneNotSupportedException: com.clone.CloneTest
at java.lang.Object.clone(Native Method)
at com.clone.CloneTest.main(CloneTest.java:6)
If Clonable interface is implemented without clone() method Overriding,
DeleteThere will be deafault cloning with Shallow copy.
public class CloneTest implements Cloneable {
public static void main(String[] args) throws CloneNotSupportedException {
CloneTest obj = new CloneTest();
CloneTest clonedObj = (CloneTest) obj.clone();
if(obj==clonedObj) {
System.out.println("equal");
} else {
System.out.println("cloned new instanse");
}
}
}
cloned new instanse
If you want to perform cloning, it is must to implement the Cloneable interface.
Deleteclone() method overriding needed when you want to perform Deep copy !!
If the Clonable (Marker interface) interface is not implemented, there will be an exception. because JVM will unable to understand that its an clonable object !
ReplyDeletepublic class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
CloneTest obj = new CloneTest();
CloneTest clonedObj = (CloneTest) obj.clone();
if(obj==clonedObj) {
System.out.println("equal");
} else {
System.out.println("cloned new instanse");
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Exception in thread "main" java.lang.CloneNotSupportedException: com.clone.CloneTest
at java.lang.Object.clone(Native Method)
at com.clone.CloneTest.clone(CloneTest.java:18)
at com.clone.CloneTest.main(CloneTest.java:6)
public class CloneTest implements Cloneable {
Deletepublic static void main(String[] args) throws CloneNotSupportedException {
CloneTest obj = new CloneTest();
CloneTest clonedObj = (CloneTest) obj.clone();
if(obj==clonedObj) {
System.out.println("equal");
} else {
System.out.println("cloned new instanse");
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Output :
loned new instanse
Well explained object cloning in java . Thanks very much for sharing good article. There is also good resource for java
ReplyDeleteclone visit Object Cloning in java
Hello mate ggreat blog
ReplyDelete