A Java deep clone (deep copy) example

While interviewing for computer programming positions here in the Boulder, Colorado area, I've found that most interviewers ask questions about Java serialization. After being asked about serialization for the third time recently, I suddenly remembered an old Java deep clone hack that takes advantage of serialization.

The basic idea is this:

  • You have a Java object, and you want to make a complete clone (copy) of it.
  • By marking your classes as being Serializable, you can write them out as an object stream, then read them back in as a different object.
  • When you read the object back in as a different object, you very quickly have a deep clone of your original object.

A Java deep clone method

Getting right to the answer, the following method will let you make a deep clone of a Java object:

/**
 * This method makes a "deep clone" of any Java object it is given.
 */
 public static Object deepClone(Object object) {
   try {
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     ObjectOutputStream oos = new ObjectOutputStream(baos);
     oos.writeObject(object);
     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
     ObjectInputStream ois = new ObjectInputStream(bais);
     return ois.readObject();
   }
   catch (Exception e) {
     e.printStackTrace();
     return null;
   }
 }

As you'll see in the following example, you can call this method something like this:

// (1) create a Person object named Al
Address address = new Address("305 West Fern Avenue", "Palmer", "Alaska");
Person al = new Person("Al", "Alexander", address);

// (2) make a deep clone of Al
Person neighbor = (Person)deepClone(al);

In this code, the neighbor object is a deep clone of the "al" object.

A complete deep clone example

If you're in a hurry, I hope that code gave you what you need. But if it helps to see a complete "deep clone" example, here's some Java source code that completely demonstrates this technique:

import java.io.*;

/**
 * Demonstrates a technique (a hack) to create a "deep clone"
 * in a Java application.
 * @author Alvin Alexander, http://alvinalexander.com
 */
public class JavaDeepClone {

  public static void main(String[] args) {
    // (1) create a Person object named Al
    Address address = new Address("305 West Fern Avenue", "Palmer", "Alaska");
    Person al = new Person("Al", "Alexander", address);
    
    // (2) make a deep clone of Al
    Person neighbor = (Person)deepClone(al);
    
    // (3) modify the neighbor's attributes
    neighbor.firstName = "Martha";
    neighbor.lastName = "Stewart";
    
    // (4) show that it all worked
    System.out.print(neighbor);
  }

  /**
   * This method makes a "deep clone" of any object it is given.
   */
  public static Object deepClone(Object object) {
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(baos);
      oos.writeObject(object);
      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
      ObjectInputStream ois = new ObjectInputStream(bais);
      return ois.readObject();
    }
    catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
}

/**
 * These classes implement Serializable so we can write them out and 
 * read them back in as a stream of bytes.
 */
class Person implements Serializable {
  String firstName, lastName;
  Address address;
  public Person(String firstName, String lastName, Address address) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.address = address;
  }
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("First Name: " + firstName + "\n");
    sb.append("Last Name: " + lastName + "\n");
    sb.append("Street: " + address.street + "\n");
    return sb.toString();
  }
}

class Address implements Serializable {
  String street, city, state;
  public Address(String street, String city, String state) {
    this.street = street;
    this.city = city;
    this.state = state;
  }
}

I've tried to document the Java source code pretty well, so I won't describe it in any further detail here, other than to add these comments:

  • I didn't create the Person and Address classes as Java beans, but only because I was trying to make this example as short as possible.
  • As you can see, the deepClone method does all the magic of making a copy/clone of your original object.

Java deep clone example - Summary

As shown, this serialization technique/hack lets you easily make a deep clone of a Java object.

As far as I know, the only drawback to this technique is that it requires you to have your classes implement the Java Serializable interface, which is considered a "marker" interface, because it does not define any methods.

I haven't had the need to use this technique in many years, so I'm certainly welcome to comments on the use of this deep clone technique.

SerializationUtils.clone()

Nice article. I have similar approach but use something simpler that is SerializationUtils.clone() from apache commons lang3 library.

Post new comment

The content of this field is kept private and will not be shown publicly.