Clone method of Object class in Java


Let me ask you a question. How will you make copy of one object and assign to another reference variable? If you think, you can use assignment operator(=) then you are wrong. Assignment operator does not copy object to another object instead new reference variable points to same object in memory.

Person obj1 = new Person();
Person obj2 = obj1;

Here both variable obj1 and obj2 points to same object to memory. Two varibles referring to same object in memory. If you change something in obj1 that will be reflected in obj2 and vice versa Below image explains this -

You can use clone method to make copy of object.
Here is code snippet of clone method from object class.

protected native Object clone() throws CloneNotSupportedException;


clone is native: The clone method is native in Object class. This method works at memory level and create copy of object. It means we don't need to create new object in code manually to make copy.
Below way of writing clone method is wrong. We should not create new object copy value of instance variable-

public class Person {
 private Integer id;
 private String name;
 
 public Person() {
 }
 public Person(Integer id, String name) {
  this.id = id;
  this.name = name;
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
  Person person = new Person();
  person.id = this.id;
  person.name = this.name;
  return person;
 }

 public static void main(String[] args) {
  Person person = new Person(1, "Parth");
  System.out.println(person);
 } 
}
clone is protected: The clone method is protected in Object class. It is property of protected method that it is only accessible within same package and sub class of different package. It is very much obvious that (1) Object class is defined in java.lang package. We will not define our class in java.lang package. (2) The class which will call clone method and the class which will define the clone method , both will not be same. I mean any class will not make copy of its own object. There will be some other class which will need copy of object and it will call clone method.
So protected modifier will not work here. Sub class need to override clone method by making it less restrict by public modifier.

class Person {
 private Integer id;
 private String name;
 
 public Person() {
 }
 
 public void setName(String name) {
  this.name = name;
 }
 
 public Person(Integer id, String name) {
  this.id = id;
  this.name = name;
 }
 
 @Override
 public String toString() {
  return "Person [id=" + id + ", name=" + name + "]";
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
  
}

public class TestMe{
 public static void main(String[] args) throws 
            CloneNotSupportedException {
  Person p1 = new Person(1, "Parth");
  Person p2 = (Person) p1.clone();
  p2.setName("Veer");
  System.out.println(p1);
  System.out.println(p2);
 }
 
}

Above program will throw CloneNotSupportedException:
Exception in thread "main" java.lang.CloneNotSupportedException: Person
at java.lang.Object.clone(Native Method)
at Person.clone(TestMe.java:24)
at TestMe.main(TestMe.java:32)

The class must implement Cloneable interface if you want to clone object of that class. Otherwise CloneNotSupportedException will be thrown. Cloneable interface is marker interface. It does not have any method.
Please find below perfectly working example:
class Person implements Cloneable{
 private Integer id;
 private String name;
 
 public Person() {
 }
 
 public void setName(String name) {
  this.name = name;
 }
 
 public Person(Integer id, String name) {
  this.id = id;
  this.name = name;
 }
 
 @Override
 public String toString() {
  return "Person [id=" + id + ", name=" + name + "]";
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
  
}

public class TestMe{
 public static void main(String[] args) throws 
 CloneNotSupportedException {
  Person p1 = new Person(1, "Parth");
  Person p2 = (Person) p1.clone();
  p2.setName("Veer");
  System.out.println(p1);
  System.out.println(p2);
 }
 
}

OUTPUT : Person [id=1, name=Parth]
Person [id=1, name=Veer]

We have create clone p2 of p1 object. Even if we changed the name properties of p2 it is reflected in p1. I means p2 object is cloned.

Comments

Popular posts from this blog

Data types and Literals in Java

How to define Auxiliary Constructor in case class in Scala

equals() method of Object class in Java