Monday, June 10, 2013

Java: What is object deep copy and how it can be achieved in Java ?

If you need to copy and object, you can do it in Java using clone method that is member method of Object class, which is all objects parent class in Java. but wait, clone method performs a shallow copy not a deep copy.

In deep copy the object is copied along with the objects it refers to. Deep clone copies all the levels of the object from top to the bottom recursively.

When a deep copy of the object is done new references are created.

One solution is to simply implement your own custom method (e.g., deepCopy()) that returns a deep copy of an instance of one of your classes. This may be the best solution if you need a complex mixture of deep and shallow copies for different fields, but has a few significant drawbacks:
  1. You must be able to modify the class (i.e., have the source code) or implement a subclass.
  2. If you have a third-party class for which you do not have the source and which is marked final, you are out of luck.
  3. You must be able to access all of the fields of the classes superclasses. If significant parts of the objectes state are contained in private fields of a superclass, you will not be able to access them.
  4. You must have a way to make copies of instances of all of the other kinds of objects that the object references. This is particularly problematic if the exact classes of referenced objects cannot be known until runtime.

Disadvantages:
Custom deep copy methods are tedious to implement, easy to get wrong, and difficult to maintain. The method must be revisited any time a change is made to the class or to any of its superclasses.

Solution 2:

Other common solution to the deep copy problem is to use Java Object Serialization (JOS).
The idea is simple:
Write the object to an array using JOSes ObjectOutputStream and then use ObjectInputStream to reconsistute a copy of the object.

The result will be a completely distinct object, with completely distinct referenced objects.

Advantages
JOS takes care of all of the details: superclass fields, following object graphs, and handling repeated references to the same object within the graph.

Note:
It will only work when the object being copied, as well as all of the other objects references directly or indirectly by the object, are serializable. (In other words, they must implement java.io.Serializable.) Fortunately it is often sufficient to simply declare that a given class implements java.io.Serializable and let Javaes default serialization mechanisms do their thing.

Disadvantage:
Java Object Serialization is slow, and using it to make a deep copy requires both serializing and deserializing.

Enhancing JOS performance:
There are ways to speed it up (e.g., by pre-computing serial version ids and defining custom readObject() and writeObject() methods), but this will usually be the primary bottleneck. The byte array stream implementations included in the java.io package are designed to be general enough to perform reasonable well for data of different sizes and to be safe to use in a multi-threaded environment.

These characteristics, however, slow down ByteArrayOutputStream and (to a lesser extent) ByteArrayInputStream.

More References on this:
Deep Copy
Java Clone mechanism
Another "Deep copy" solutions and techniques.

No comments :

Post a Comment