Clone Under standing

Clone
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());
            }

}



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

Previous
Next Post »