We all know that easiest way of deep cloning (with some performance overhead) or deep copy is Serialization. Java serialization involves serializing the object into bytes and from bytes to object again.
I will suggest you to use in memory deep cloning whenever it is the only need and you don’t need to persist the object for future use. In this Java deep cloning example, I will suggest one mechanism of in-memory deep cloning for your reference.
Please remember that deep cloning is evil for singleton pattern. It makes possible of having multiple instances of singleton classes.
Read more : Java Object Cloning Guide
1. Java deep copy example
In demonstration program, I have created a demo class named SerializableClass
. This has three variables i.e. firstName
, lastName
and permissions
. I will add a deepCopy() instance level method to this class. Whenever invoked on an instance of SerializableClass
, it will return exact clone / deep copy of that instance.
For deep cloning, we have to first serialization and then deserialization. For serialization, I have used ByteArrayOutputStream
and ObjectOutputStream
. For deserialization, I have used ByteArrayInputStream
and ObjectInputStream
.
package serializationTest; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.List; public class SerializableClass implements Serializable { private static final long serialVersionUID = 1L; private String firstName = null; private String lastName = null; @SuppressWarnings("serial") private List permissions = new ArrayList() { { add("ADMIN"); add("USER"); } }; public SerializableClass(final String fName, final String lName) { //validateNameParts(fName); //validateNameParts(lName); this.firstName = fName; this.lastName = lName; } public SerializableClass deepCopy() throws Exception { //Serialization of object ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(this); //De-serialization of object ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bis); SerializableClass copied = (SerializableClass) in.readObject(); //Verify that object is not corrupt //validateNameParts(fName); //validateNameParts(lName); return copied; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @Override public String toString() { return new StringBuilder().append(getFirstName()+",") .append(getLastName()+",") .append(permissions) .toString(); } }
2. Demo
Lets test the class and create deep copy of instance to verify if it works as expected.
package serializationTest; public class ImMemoryTest { public static void main(String[] args) throws Exception { //Create instance of serializable object SerializableClass myClass = new SerializableClass("Lokesh","Gupta"); //Verify the content System.out.println(myClass); //Now create a deep copy of it SerializableClass deepCopiedInstance = myClass.deepCopy(); //Again verify the content System.out.println(deepCopiedInstance); } }
Program Output.
Lokesh,Gupta,[ADMIN, USER] Lokesh,Gupta,[ADMIN, USER]
Before considering in-memory deep copy objects in your application, you might like to read about serialization guidelines which will prevent your design from breaking in future.
Happy Learning !!
Read More:
Leave a Reply