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 aCar
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 ofCar
, using a String and initializes the String field, using another String. Person
overrides theclone()
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 thePerson
class to the outputStream, withwriteObject(Objet obj)
API method of ObjectOutputStream. Then a newly allocated byte array is created , withtoByteArray()
API method of ByteArrayOutputStream, and using it a new ByteArrayInputStream is created to read the object that was above writen to the outputStream, withreadObject()
API method of ObjectInputStream. We create a new instance ofPerson
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 ofCar
inPerson
class and then the getter of the String field ofCar
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 thePerson
constructor. - We change the two String field in clone
Person
object and inCar
field of clonePerson
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.