An Introduction To Deep Cloning in Java Part 2

Posted By : Aftab Alam | 12-May-2020

1. Introduction

As a Java developer, it's very much important to know about deep cloning mechanism. In this blog, we are going to have a closer look at the concept of cloning in Java application development.

In Java app development services, cloning is a mechanism in which an object is created from another object without using the new operator. It has been categorized in categories.

  1. Swallow Cloning

  2. Deep Cloning

 

2. Requirements

Have a look at the pre-requisites given below:

   2.1. Ubuntu 14.04 LTS

   2.2. Ubuntu gedit editor

   2.3. java version "1.8.0_181" 

 

3. Implementation

It has been divided into multiple steps.

   3.1. Deep Cloning:- As we have seen in case of swallow cloning, only object's primitive(Integer, Float, Double, Character, Boolean, String, etc) properties are cloned. In other words, Object's primitive data-member(s)/properties get separate memory as same as while creating an object using the new operator except reference variables(user defined classes, map, and list). Deep cloning is not directly supported by Java. For achieving deep cloning, we need to write down logic explicitly to achieve it.

  3.1.1. Student:- It has three properties id, name, and a list of courses in which two are primitive type while third one is a list of reference type. It implements a cloneable interface by which primitive properties can be cloned for an instance by overriding its clone method but a list of reference type(List<Course?) can not be. So for cloning user defined class(List<Course>), Course class has to implement cloneable interface, needs to override clone method and its holding class(Student) has to implement logic for cloning as well.

import java.util.*;
class Student implements Cloneable {
  
   Long id;
   String name;
   List<Course> courses;

   public Student(Long id, String name, List<Course> courses) {
     this.id = id;
     this.name = name;
     this.courses = courses;
   }
 
   public String getName() {
      return name;
   }
  
   public Long getId() {
     return id;
   }

   public List<Course> getCourses() {
     return courses;
   }

   void setName(String name) {
      this.name = name;
   }

   void setId(Long id) {
      this.id = id;
   }

   void setCourses(List<Course> courses) {
      this.courses = courses;
   }

   public Student clone() {
     try {
       Student student = (Student)super.clone();
       List<Course> courses = new ArrayList();
       for(int i=0; i<this.courses.size(); i++) {
         courses.add(this.courses.get(i).clone());
       }
       student.courses = courses;
       return student;
      } catch(Exception E) {
         System.out.println("Ex: "+E.getMessage());
	return new Student(0l, "Excep", new ArrayList<Course>());
      }
   }
}

3.1.2. Course:- It has two primitive properties id and name. It implements cloneable interface and overrides clone meethod from it.

class Course implements Cloneable {
  
   Long id;
   String name;

   public Course(Long id, String name) {
      this.id = id;
      this.name = name;
   }

   public String getName() {
      return name;
   }
  
   public Long getId() {
     return id;
   }

   void setName(String name) {
      this.name = name;
   }

   void setId(Long id) {
      this.id = id;
   }

   public Course clone() {
     try {
       return (Course)super.clone();
      } catch(Exception E) {
        System.out.println("Ex: "+E.getMessage());
	return null;
      }
   }
}

 3.1.3. DeepCloningPartIIDemo

It demonstrates working of deep cloning. In this class, an instance of student and course classes is created. When student class is cloned then a list of coursees class is separately is created.  

public class DeepCloningPartIIDemo {

   public static void main(String a[]) {
      Course course1 = new Course(1l, "Java");
      Course course2 = new Course(2l, "A Java");
      List<Course> courses = new ArrayList();
      courses.add(course1);
      courses.add(course2);
      Student student1 = new Student(1000l, "Aftab", courses);
      System.out.println("Name1: "+student1.getName());
      System.out.println("Roll No1: "+student1.getId());
      Student student2 = student1.clone();
      System.out.println("Name1: "+student2.getName());
      System.out.println("Roll No2: "+student2.getId());
      student1.setName("Khan");
      System.out.println("Name1: "+student1.getName());
      System.out.println("Roll No1: "+student1.getId());
      System.out.println("Name1: "+student2.getName());
      System.out.println("Roll No2: "+student2.getId());

      System.out.println("Course Name1: "+student1.getCourses().get(0).getName()); 
      System.out.println("Course Name2: "+student2.getCourses().get(0).getName());  
      System.out.println("Course Name1: "+student1.getCourses().get(1).getName()); 
      System.out.println("Course Name2: "+student2.getCourses().get(1).getName());    
      student1.getCourses().get(0).setName("C++"); 
      student1.getCourses().get(1).setName("C");  
      System.out.println("After Course Name1: "+student1.getCourses().get(0).getName()); 
      System.out.println("After Course Name2: "+student2.getCourses().get(0).getName()); 
      System.out.println("After Course Name1: "+student1.getCourses().get(1).getName()); 
      System.out.println("After Course Name2: "+student2.getCourses().get(1).getName());      
   }
}

3.2. Commands

To compile and execute this program, listed below commands are used on ubuntu terminal.

     3.2.1. "javac DeepCloningPartIIDemo.java" to compile the java program

     3.2.2. "java DeepCloningPartIIDemo" to execute the program which produces the result shown in below screenshot.

 

3.3. Output

When the above program is executed then It produces an output which is shown in the screenshot.

 

4. Conclusion

In Java application development, it is best suited when every instance of parent class wants to have a separate copy of list of its reference type variable(class). 

About Author

Author Image
Aftab Alam

Aftab has worked on multiple technologies in front-end as well as in back-end.

Request for Proposal

Name is required

Comment is required

Sending message..