Header Ads Widget

Responsive Advertisement

Clone Under standing

Clone

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:

  1. 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.

  1. 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.

  1. 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.


1.  What is java exactly do in assignment operator?
In Java, when you assign an object to another variable, only the memory address of the object is copied and hence any changes in the original object will be reflected in the new variable.
Object obj1=new Object ();
Object obj2 =null;
obj2 = obj1;
Here, in this case any changes you make to obj1 will reflect in obj2 and vice versa. Well, if this is what you want, then no issues but if you don’t want the change made in obj2 to be seen in obj1 or any change made in obj1 to be seen in obj2, then cloning comes into picture.
2.  So why need Clone?
Well, cloning means creating a copy of the 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:
·          x.clone();  // will be true, and that the expression:
·          x.clone().getClass() ==x.getClass() // will be true, but these are not absolute requirements. While it is typically the case that
·          x.clone().equals(x);// will be true, and this is also not an absolute requirement.
3.  Type of Clone
3.1. Shallow clone
3.2. Deep clone
4.  What is shallow clone

This is default implementation in java. In overridden clone method, if you are not cloning all the object types (not primitives), then you are making a shallow copy.
Example:
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

5.  Deep clone
5.1. We want a clone which is independent of original and making changes in clone should not affect original.
5.2. Example of Deep clone
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());
            }

}


Fig A
Fig A

Output:
com.clon.Employee@16721ee7
com.clon.Employee@1e4adb34
Human Resource
Software
Finance
Admin
ABC
DDD
ABC



Fig b will give the more realistic example



Clone image B

Clone image B




Post a Comment

0 Comments