In Java, the concept of "cloning" refers to
creating an exact copy of an object. This is typically done using the clone()
method, which is part of the Object class.
Key Points about Cloning in Java:
- Shallow
Copy vs. Deep Copy:
Ø
Shallow Copy: The default behavior of the
clone() method provided by the Object class is to perform a shallow copy. This
means that it creates a new instance of the object, but the fields of the
object that are references to other objects (like arrays or objects) are not
copied. Instead, the references are copied, so both the original and the clone
point to the same objects in memory.
Ø
Deep Copy: A deep copy, on the other
hand, means that all objects are recursively cloned, resulting in a completely
independent copy of the original object. Java doesn't provide a built-in deep
copy mechanism, so it must be implemented manually.
- Implementing
Cloning:
Ø
To use the clone() method, a class must
implement the Cloneable interface. This interface doesn't have any methods; it
simply indicates that the class supports cloning.
Ø
If the clone() method is called on an object
that doesn't implement Cloneable, the method will throw a CloneNotSupportedException.
- Overriding
the clone() Method:
Ø
When you override the clone() method, you should
make it public (the default clone() method in the Object class is protected).
Ø
In your overridden clone() method, you can
control how deep or shallow the cloning process should be.
package com.clone;
public class
Department
{
private int id;
private String name;
public Department(int id,
String name)
{
this.id = id;
this.name = name;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int
id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void
setName(String name) {
this.name = name;
}
}
|
package com.clone;
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;
}
@Override
protected
Object clone() throws CloneNotSupportedException {
return
super.clone();
}
/**
* @return the empoyeeId
*/
public int
getEmpoyeeId() {
return empoyeeId;
}
/**
* @param empoyeeId the empoyeeId to
set
*/
public void
setEmpoyeeId(int empoyeeId) {
this.empoyeeId =
empoyeeId;
}
/**
* @return the employeeName
*/
public String getEmployeeName()
{
return employeeName;
}
/**
* @param employeeName the
employeeName to set
*/
public void
setEmployeeName(String employeeName) {
this.employeeName =
employeeName;
}
/**
* @return the department
*/
public Department
getDepartment() {
return department;
}
/**
* @param department the department to
set
*/
public void
setDepartment(Department department) {
this.department =
department;
}
}
|
package com.clone;
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);
// Employee original = new Employee(1, "Admin");
//Lets create a clone of original object
System.out.println(original);
Employee cloned =
(Employee) original.clone();
System.out.println(cloned);
//Let verify using employee id, if cloning actually workded
/*System.out.println(cloned.getEmpoyeeId());
//Verify JDK's rules
//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));*/
//Shallow clone example where department not done any clone so it will
done as same Behavior of object assignment
//but in Employee class is done cloning so only it will effect in
employee class object
cloned.getDepartment().setName("Finance");
original.getDepartment().setName("Software");
System.out.println(original.getDepartment().getName());
System.out.println(cloned.getDepartment().getName());
//System.out.println(original.getEmployeeName());
//This is Employee class clone data changes
cloned.setEmployeeName("ABC");
System.out.println(original.getEmployeeName());
System.out.println(cloned.getEmployeeName());
original.setEmployeeName("DDD");
System.out.println(original.getEmployeeName());
System.out.println(cloned.getEmployeeName());
}
}
|
OutPut:
com.clone.Employee@447d4275
com.clone.Employee@7b963273
Software
Software
Admin
ABC
DDD
ABC
|
package com.clon;
public class
Department implements Cloneable
{
private int id;
private String name;
public Department(int id,
String name)
{
this.id = id;
this.name = name;
}
@Override
protected Object clone() throws
CloneNotSupportedException {
return
super.clone();
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int
id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void
setName(String name) {
this.name = name;
}
}
|
package com.clon;
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;
}
@Override
protected
Object clone() throws CloneNotSupportedException {
Employee
cloned = (Employee)super.clone();
cloned.setDepartment((Department)cloned.getDepartment().clone());
return
cloned;
}
/**
* @return the empoyeeId
*/
public int
getEmpoyeeId() {
return empoyeeId;
}
/**
* @param empoyeeId the empoyeeId to
set
*/
public void
setEmpoyeeId(int empoyeeId) {
this.empoyeeId =
empoyeeId;
}
/**
* @return the employeeName
*/
public String getEmployeeName()
{
return employeeName;
}
/**
* @param employeeName the
employeeName to set
*/
public void
setEmployeeName(String employeeName) {
this.employeeName =
employeeName;
}
/**
* @return the department
*/
public Department
getDepartment() {
return department;
}
/**
* @param department the department to
set
*/
public void
setDepartment(Department department) {
this.department =
department;
}
}
|
package com.clon;
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);
// Employee original = new Employee(1, "Admin");
//Lets create a clone of original object
System.out.println(original);
Employee cloned =
(Employee) original.clone();
System.out.println(cloned);
//Let verify using employee id, if cloning actually workded
/* System.out.println(cloned.getEmpoyeeId());
//Verify JDK's rules
//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));*/
//this is for hole class need to clone
System.out.println(original.getDepartment().getName());
cloned.getDepartment().setName("Finance");
original.getDepartment().setName("Software");
System.out.println(original.getDepartment().getName());
System.out.println(cloned.getDepartment().getName());
cloned.setEmployeeName("ABC");
System.out.println(original.getEmployeeName());
System.out.println(cloned.getEmployeeName());
original.setEmployeeName("DDD");
System.out.println(original.getEmployeeName());
System.out.println(cloned.getEmployeeName());
}
}
|
Output: com.clon.Employee@16721ee7 com.clon.Employee@1e4adb34 Human Resource Software Finance Admin ABC DDD ABC |
0 Comments