Back when I was interviewing for computer programming positions in Boulder and Louisville, Colorado, I found that many interviewers ask questions about Java serialization. After being asked about serialization for the third time, I remembered an old Java deep clone hack that takes advantage of serialization.
The basic idea is:
- 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, this creates a deep clone of your original object.
A Java “deep clone” method
Getting right to the solution, 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. * @author Alvin Alexander, https://alvinalexander.com */ 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("101 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, https://alvinalexander.com */ public class JavaDeepClone { public static void main(String[] args) { // (1) create a Person object named Al Address address = new Address("101 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 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
andAddress
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.
Summary: My Java deep clone example
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.
As a final note, I haven’t had the need to use this technique in a long time, so there may be better ways of doing this these days. But I can say that this technique worked well back in the day.