Open In App

Understanding Object Cloning in Java with Examples

In this article we discuss the Cloneable interface that indicates that a class has provided a safe clone() method. To understand what cloning means recall what happens when you make a copy of a variable holding an object reference. The original and the copy are references to the same object. This means the original and the copy are mutually dependent, i.e., a change in one causes a change in the other as well.
If we would like a copy to be a new object that begins its life being identical to the original but whose state can change over time we must use the clone() method.
The clone() method is declared protected in the Object class, so our code can’t simply call obj.clone(). Now we might ask, but aren’t protected methods accessible from any subclass and isn’t every class a subclass of Object. Fortunately the rules for protected access are much more subtle. A subclass can call protected clone() method to clone its own objects. We must redefine clone to be public to be accessed by any methods. 
Even though the default implementation of clone is adequate, you still need to implement the Cloneable interface, redefine clone() method to be public, and call public.
Example: 




class Student implements Cloneable {
 
    // raise visibility level to public
    // and change the return type
    public Student clone()
        throws CloneNotSupportedException
    {
        return (Student)super.clone();
    }
    .
        .
        .
}

The clone() method that you just saw adds no functionality to the copy provided by Object.clone. It merely makes the method public and changes its return type. To make a deeper copy, we must clone the mutable instance fields.
This is the modified version
 






class Student implements Cloneable {
 
    // other components
 
    public Student clone()
        throws CloneNotSupportedException
    {
 
        // call Object.clone()
        Student obj = (Student)super.clone();
 
        // clone mutable fields
        obj.birthDay = (Date)birthDay.clone();
    }
}

The clone() method of Object will try to throw a ClassNotSupportedException whenever clone is invoked on a class that does not implement the Cloneable interface.
Example: 
 




import java.util.Date;
import java.util.GregorianCalendar;
 
public class Employee implements Cloneable {
 
    private String name;
    private double salary;
    private Date hireDay;
 
    public Employee(String name, double salary)
    {
        this.name = name;
        this.salary = salary;
        hireDay = new Date();
    }
 
    public Employee clone()
        throws CloneNotSupportedException
    {
 
        // call Object.clone()
        Employee obj = (Employee)super.clone();
 
        // clone mutable fields
        obj.hireDay = (Date)hireDay.clone();
 
        return obj;
    }
 
    // Set the hireDay to a given date
    public void setHireDay(int year, int month, int day)
    {
 
        Date newHireDay
            = new GregorianCalendar(year,
                                    month - 1,
                                    day)
                  .getTime();
 
        // instance field mutation
        hireDay.setTime(newHireDay.getTime());
    }
 
    public void raiseSalary(double byPercent)
    {
 
        double raise = salary * byPercent / 100;
        salary += raise;
    }
 
    public String toString()
    {
        return ("Employee[name=" + name
                + ", salary=" + salary
                + ", hireDay=" + hireDay
                + "]");
    }
 
    // main
    public static void main(String[] args)
    {
 
        try {
 
            Employee original
                = new Employee("ABC X. YZ", 50000);
 
            original.setHireDay(2000, 1, 1);
            Employee copy = original.clone();
 
            copy.raiseSalary(10);
            copy.setHireDay(2002, 12, 31);
 
            System.out.println("original= " + original);
            System.out.println("copy= " + copy);
        }
 
        catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

Output:
original= Employee[name=ABC X. YZ, salary=50000.0, hireDay=Sat Jan 01 00:00:00 UTC 2000] 
copy= Employee[name=ABC X. YZ, salary=55000.0, hireDay=Tue Dec 31 00:00:00 UTC 2002]
 

Advantages of Cloning: 



Application of Cloning in Java


Article Tags :