class

Use serializable interface to perform deep copy

With this example we are going to demonstrate how to use the Serializable interface to perform a deep copy of a class. Classes implement the Serializable interface in order to have their state serialized or deserialized. In short, to use the Serializable interface to perform a deep copy of a class:

  • We have created a class, Car that implements the Serializable interface. It has a private String field and a setter and getter method for the field. It also has a constructor using its field.
  • We have also created another class, Person, that implements the Cloneable and the Serializable interfaces. It has a Car field and a String field. It also has getter methods for its fields and a setter method for its String field. It has a constructor where it creates a new instance of Car, using a String and initializes the String field, using another String.
  • Person overrides the clone() method inherited from Object. In this method a new null object is created, and using a new ByteArrayOutputStream it creates a new ObjectOutputStream, and writes the instance of the Person class to the outputStream, with writeObject(Objet obj) API method of ObjectOutputStream. Then a newly allocated byte array is created , with toByteArray() API method of ByteArrayOutputStream, and using it a new ByteArrayInputStream is created to read the object that was above writen to the outputStream, with readObject() API method of ObjectInputStream. We create a new instance of Person and call its getter for its String field to get its String field’s value.
  • In order to get the String field of its Car field, we use the getter of Car in Person class and then the getter of the String field of Car class.
  • We create a new instance of Person, using the overriden clone() method, and again use the above getters to get the String fields of the two classes. Both objects have the same values that were used in the Person constructor.
  • We change the two String field in clone Person object and in Car field of clone Person object. The clone object now has different values in its fields, but the original object still holds its initial values.

Let’s take a look at the code snippet that follows:  

package com.javacodegeeks.snippets.core;

import java.io.*;

public class UseSerializable {

    public static void main(String[] args) {


  //Original Object

  Person person1 = new Person("Person-A", "Civic");

  System.out.println("Original (orginal values): " + person1.getN() + " - "


    + person1.getC().getN());


  //Clone as a shallow copy

  Person person2 = (Person) person1.clone();


  System.out.println("Clone (before change): " + person2.getN() + " - "


    + person2.getC().getN());


  //change the primitive member

  person2.setN("Person-B");


  //change the lower-level object

  person2.getC().setN("Accord");


  System.out.println("Clone (after change): " + person2.getN() + " - "


    + person2.getC().getN());


  System.out.println("Original (after clone is modified): " + person1.getN()


    + " - " + person1.getC().getN());
    }
}

class Person implements Cloneable, Serializable {
    //Lower-level object

    private Car car;
    private String name;

    public Car getC() {

  return car;
    }

    public String getN() {

  return name;
    }

    public void setN(String s) {

  name = s;
    }

    public Person(String s, String t) {

  name = s;

  car = new Car(t);
    }

    @Override
    public Object clone() {

  Object clonedObj = null;

  try {


ByteArrayOutputStream baos = new ByteArrayOutputStream();


try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {


    oos.writeObject(this);


}



ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());


ObjectInputStream ois = new ObjectInputStream(bais);


clonedObj = ois.readObject();


ois.close();

  } catch (IOException | ClassNotFoundException cnfe) {


System.out.println("Class not found " + cnfe);

  }

  return clonedObj;

    }
}

class Car implements Serializable {

    private String name;

    public String getN() {

  return name;
    }

    public void setN(String s) {

  name = s;
    }

    public Car(String s) {

  name = s;
    }
}

Output:

Original (orginal values): Person-A - Civic
Clone (before change): Person-A - Civic
Clone (after change): Person-B - Accord
Original (after clone is modified): Person-A - Civic

  
This was an example of how to use the Serializable interface to perform a deep copy of a class in Java.

Byron Kiourtzoglou

Byron is a master software engineer working in the IT and Telecom domains. He is an applications developer in a wide variety of applications/services. He is currently acting as the team leader and technical architect for a proprietary service creation and integration platform for both the IT and Telecom industries in addition to a in-house big data real-time analytics solution. He is always fascinated by SOA, middleware services and mobile development. Byron is co-founder and Executive Editor at Java Code Geeks.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button