When overriding clone method, why do we need to declare it as public in Java?


The clone() method belongs to the class named Object of the java.lang package, it accepts an object as a parameter creates and returns a copy of it.

In order to use this method, you need to make sure that your class implements the Cloneable (marker) interface.

Example

 Live Demo

public class CloneExample implements Cloneable {
   private String name;
   private int age;
   public CloneExample(String name, int age){
      this.name = name;
      this.age = age;
   }
   public void displayData(){
      System.out.println("Name : "+this.name);
      System.out.println("Age : "+this.age);
   }
   public static void main(String[] args) throws CloneNotSupportedException {
      CloneExample std = new CloneExample("Krishna", 25);
      System.out.println("Contents of the original object");
      std.displayData();
      System.out.println("Contents of the copied object");
      CloneExample copiedStd = (CloneExample) std.clone();
      copiedStd.displayData();
   }
}

Output

Contents of the original object
Name : Krishna
Age : 25
Contents of the copied object
Name : Krishna
Age : 25

Using the clone method you can perform two types of copying −

  • Shallow copy − While copying an object if it contains any objects as fields then, only references to those objects are copied not the compete for objects. By default, the clone() method does a shallow copy.
  • Deep copy− In the deep copy all fields of the original objects are copied exactly, in addition to this, if it contains any objects as fields then a copy of those is also created (using the clone() method).

Therefore, to perform deep copy you need to override the clone() method of the object class.

Access specifier of the clone() method

The clone() method in the java.lang.Object class is protected. The protected specifier before a method makes it accessible only to the subclasses of the current class, Since Object is the superclass of all classes in Java, protected specifier before the clone() method in the Object class makes sense.

If you override the clone method() of the object class and declare it protected it is access able only to the subclasses of the current class.

Example

Assume we have two classes namely Contact and Student data in a package named myPackage1 as shown below.

Contact.java

package myPackage1;
public class Contact implements Cloneable{
   private long phoneNo;
   private String email;
   public Contact(long phoneNo, String email ){
      this.phoneNo = phoneNo;
      this.email = email;
   }
   public void displayContact() {
      System.out.println("Phone no: "+this.phoneNo);
      System.out.println("Email: "+this.email);
   }
   protected Object clone() throws CloneNotSupportedException{
      return super.clone();
   }
}

StudentData.java

package myPackage1;
public class StudentData implements Cloneable {
   private String name;
   private int age;
   private Contact contact;
   public StudentData(String name, int age, Contact contact){
      this.name = name;
      this.age = age;
      this.contact = contact;
   }
   public void displayData(){
      System.out.println("Name : "+this.name);
      System.out.println("Age : "+this.age);
      contact.displayContact();
   }
   protected Object clone() throws CloneNotSupportedException{
      StudentData student = (StudentData) super.clone();
      student.contact = (Contact) contact.clone();
      return student;
   }
}

You can compile the above two classes as −

D:\>javac -d . Contact.java
D:\>javac -d . StudentData.java

From a class in another package named myPackage, we are trying access the clone() method of the StudentData class as shown below −

Example

package myPackage2;
import myPackage1.Contact;
import myPackage1.StudentData;
public class CloneExample{
   public static void main(String[] args) throws CloneNotSupportedException {
      //Creating an object of the class
      StudentData std = new StudentData("Krishna", 25, new Contact(9848022338L, "Krishna_test@mymail.com"));
      //Creating a clone of the above object
      StudentData copiedStd = (StudentData) std.clone();
      System.out.println("Contents of the copied object::");
      copiedStd.displayData();
      System.out.println(" ");
      System.out.println("Contents of the original object::");
      std.displayData();
   }
}

Compile-time error

When you try to compile the above class, since you are trying to access the implemented clone() method, which is declared protected, from another package a compile-time error will be generated as −

D:\>javac -d . CloneExample.java
CloneExample.java:10: error: clone() has protected access in StudentData
   StudentData copiedStd = (StudentData) std.clone();
                                             ^
1 error

Therefore, while overriding the clone() method it is recommended to declare it public instead of protected so that it is access-able from a class in any location in the system.

While overriding methods the method in the child class must not have higher access restrictions than the one in the superclass. Since the public is lower restriction than protected it is allowed to change the access specifier from protected to public in the overridden method.

raja
Published on 10-Sep-2019 14:49:07
Advertisements