August 28, 2022

Object Cloning in Java Using clone() Method

Object cloning in Java is the process of creating a copy of an object. To clone an object in Java clone() method of the Object class is used.

clone() method

clone() method is defined in the Object class as a protected method.

protected Object clone() throws CloneNotSupportedException

If you are going to write a clone() method in your class to override the one in Object class then it has to be written as a public method.

public Object clone() throws CloneNotSupportedException

Cloning an object in Java using clone() method

One of the requirement for cloning an object is that the class whose objects are to be cloned must implement Cloneable interface. Cloneable interface is a marker interface and defines no members of its own. If you try to call clone() method on a class that does not implement Cloneable interface, a CloneNotSupportedException is thrown.

If you have to create a clone of an object obj using clone() method then you write-

obj.clone();

Default implementation of the clone() method creates an object of the same class as the original object. Cloned object's member variables are initialized to have the same values as the original object's corresponding member variables.

Examples of Java object cloning

Here is a simple example of cloning an object by directly calling clone() method of the Object class using super.

class TestClone implements Cloneable{
  int i;
  String str;
  TestClone(int i, String str){
    this.i = i;
    this.str = str;
  }
  TestClone cloneObject() throws CloneNotSupportedException{
    // calling Object class clone method
    return (TestClone) super.clone();
  }
}

public class CloningDemo {
  public static void main(String[] args) {
    TestClone obj1 = new TestClone(10, "Clone Test");
    try {
      TestClone obj2 = obj1.cloneObject();
      System.out.println("Original object- " + obj1.i + " " + obj1.str);
      System.out.println("Cloned object- " + obj2.i + " " + obj2.str);
      // Checking object references for objects
      if(obj1 == obj2){
        System.out.println("Object references are same");
      }else{
        System.out.println("Object references are not same");
      }
    } catch (CloneNotSupportedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 			
  }
}
Output
Original object- 10 Clone Test
Cloned object- 10 Clone Test
Object references are not same

In the code you can note what all is done for object cloning-

  1. Class whose object is to be cloned implements Cloneable interface.
  2. super.clone() is called to use the default implementation of the clone() method in the Object class.
  3. You can see that the copy of an object has the same state as the original object (same value for the member variables as original object).
  4. Though the state is same but the reference is not same. Cloned object is distinct.
Override clone method in the class

You can also override the clone method in the class though it is not always necessary.

class TestClone implements Cloneable{
  int i;
  String str;
  TestClone(int i, String str){
    this.i = i;
    this.str = str;
  }
  // overriding clone method
  public Object clone() throws CloneNotSupportedException{
    return super.clone();
  }
}

public class CloningDemo {
  public static void main(String[] args) {
    TestClone obj1 = new TestClone(10, "Clone Test");
    try {
      TestClone obj2 = (TestClone) obj1.clone();
      System.out.println("Original object- " + obj1.i + " " + obj1.str);
      System.out.println("Cloned object- " + obj2.i + " " + obj2.str);
    } catch (CloneNotSupportedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 			
  }
}
Output
Original object- 10 Clone Test
Cloned object- 10 Clone Test

Advantages of object cloning

  1. Object cloning in Java is the easiest way to get a new object with a state. You don’t need to go through the whole process of calling new operator to create an object and assign value to its fields.
  2. Cloned object is a distinct object with its own state. Changing one of the object doesn’t change the state of the other object.

Disadvantages of object cloning

  1. Though using the default clone() method make the process of cloning an object automatic but at the same time you don’t have any control over the whole process. Even the constructor is not called when object is cloned.
  2. Object.clone() method creates a shallow copy. That is fine if the fields in an object are primitive or immutable. In case original object holds reference to another object then that reference is shared between original and cloned object which may be a problem.

Object cloning - Shallow copy

When an object is cloned a bit wise copy happened where each field’s value in the original object is copied to the cloned object’s corresponding field. This way of object cloning in Java is known as Shallow copy. This works fine for primitive values as we have already seen in the examples.

But this process of creating an exact copy may have a problem when object holds reference to another object because that reference is copied as it is in the cloned object and both objects share that object reference. That’s when you may need a deep copy.

Java Object cloning - Deep copy

You need to do a deep copy if you don’t want any object references to be copied as it is during the object cloning process.

For creating a deep copy you need to explicitly override the clone() method in your class and call the clone() method for the objects referenced by the original object too.

Creating a Deep copy is more expensive as you need to create new objects for all the referenced objects. It is more complicated too as there may be a whole object tree that you may need to clone.

To know more about Shallow copy and Deep copy in Java object cloning please refer this post- Shallow Copy Vs Deep Copy in Java Object Cloning

Object cloning in Java - Deep copy example

In the example there are two classes One and Two. In Class Two there is a reference to an object of class One. In order to do a deep copy clone() method is overridden in class Two and clone() method for the referenced object (object of class One) is also called explicitly to create a distinct copy of that object too.

class One implements Cloneable{
  int i;
  String str;
  One(int i, String str){
    this.i = i;
    this.str = str;
  }
  // overriding clone method
  public Object clone() throws CloneNotSupportedException{
    return super.clone();
  }
  public int getI() {
    return i;
  }
  public void setI(int i) {
    this.i = i;
  }
  public String getStr() {
    return str;
  }
  public void setStr(String str) {
    this.str = str;
  }
}

class Two implements Cloneable{
  int j;
  // Object reference
  One obj;
  Two(int j, One obj){
    this.j = j;
    this.obj = obj;
  }
  public Object clone() throws CloneNotSupportedException{
    Two objCloned =  (Two) super.clone();
    // Explicitly calling clone method for
    // object of Class One
    objCloned.obj = (One) obj.clone();
    return objCloned;
  }
  public int getJ() {
    return j;
  }
  public void setJ(int j) {
    this.j = j;
  }
  public One getObj() {
    return obj;
  }
  public void setObj(One obj) {
    this.obj = obj;
  }
}

public class CloningDemo {
  public static void main(String[] args) {
    One one = new One(10, "Clone Test");
    Two two = new Two(5, one);
    try {
      Two objCopy = (Two) two.clone();
      System.out.println("Original object- " +  two.getJ() + " " + two.getObj().str);
      System.out.println("Cloned object- " +  + objCopy.getJ() + " " + objCopy.getObj().str);
      objCopy.getObj().setStr("Value changed");
      System.out.println("---After changing value---");
      System.out.println("Original object- " +  two.getJ() + " " + two.getObj().str);
      System.out.println("Cloned object- " +  + objCopy.getJ() + " " + objCopy.getObj().str);
    } catch (CloneNotSupportedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 			
  }
}
Output
Original object- 5 Clone Test
Cloned object- 5 Clone Test
---After changing value---
Original object- 5 Clone Test
Cloned object- 5 Value changed

As you can see from the output when the str field is modified in class One object referenced by the cloned object that change is not reflected in the original object because of the deep copy.

That's all for the topic Object Cloning in Java Using clone() Method. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment