Today we will look into Java deep copy. Sometimes we want to get a copy of an Object, but java works on reference and if we don’t want to alter the original object then we need to perform deep copy. In simple terms, deep copy of an Object should be completely detached from the original object.
Java Deep Copy
One of the way to get a deep copy of an Object is using Serialization. Just to revise, Serialization in Java allows us to convert an Object to stream that we can send over the network or save it as file or store in DB for later usage.
Let’s keep that in mind and hover over the basic idea behind deep copy in Java.
The basic idea behind deep copy in java is:
- There is a Java object which is needed to be cloned (deeply).
- First step is to mark the Model object as Serializable so that the object can converted into a Stream so that it can be written in a file/stream ond can be read back.
- When the object is read back, we get a deep clone of the original object.
- Note that this method works fine when the class you want to deep copy is serializable and all of it’s variables are also Serializable. Otherwise it will not work and you will get
java.io.NotSerializableException
. - If the classes are not serializable, then the only option is to write a custom method to take care of copying object variables field by field to get a deep copy.
How to do Deep Copy?
Now that was the process through which we can deep copy of an object is outlined. Let’s see how it’s done programmatically:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/** * Makes a deep copy of any Java object that is passed. */ private static Object deepCopy(Object object) { try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream outputStrm = new ObjectOutputStream(outputStream); outputStrm.writeObject(object); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); ObjectInputStream objInputStream = new ObjectInputStream(inputStream); return objInputStream.readObject(); } catch (Exception e) { e.printStackTrace(); return null; } } |
Above method accepts an Object and return its deep copy.
This method is a ready-to-use method. It can be called as:
1 2 3 4 5 |
//Student should be Serializable, primitive and Strings are Serilizable too. Student john = new Student("John", 13, "23, 23rd Street, Goa"); Student abraham = (Student) deepCopy(john); |
Deep Copy vs Shallow Copy
As we saw, deep copy is a pretty simple concept but still, it is confused with terms like shallow copy of an Object.
It is important to understand that a shallow copy is just another reference to the same Object. Let’s see through code how a Shallow Copy can be made for an Object:
1 2 3 4 5 6 7 |
List firstList, secondList; firstList = new ArrayList(); firstList.add("Hello:); secondList = firstList; secondList.add("World"); |
In above example, the statement secondList = firstList;
makes a shallow copy of the firstList. When the second element is added to the secondList, it also means that the firstList contains two elements as well because both the lists are actually the same.
Object clone() method
Object clone() method is generally thought to produce a copy of the target object.
Here’s what the javadoc says:
Note, that this states that at one side the clone might be the target object, and at the other side the clone might not even be equal to the actual object. And this assumes if clone is even supported.
To summarise, the clone can mean significantly different for every Java class.
Conclusion
In this lesson, we looked on how to implement java deep copy for an Object. We also cleared some ill-understanding between cloning and Shallow copy of objects and defined what clone() method in Java actually refers to.