Java supports two different types of cloning
- Shallow cloning - java's object.clone() gives a shallow copy of the object being cloned. Here the object cloned is copied without its contained object. Shallow cloning is a bitwise copy of an object. New object is created which is an exact copy of the original one. In case of contained objects just the references are copied.
- Deep cloning - as object.clone() method yields shallow copy, to achieve deep copy classes needs to be adjusted (check note below). Here the original object is copied along with its contained objects (note: here the entire graph of objects are traversed and copied.) Each object in the graph is responsible of cloning itself through the clone method.So, In deep cloning, complete duplicate copy of the original copy is created.
- If the object wants to be able to clone itself it first needs to implement Cloneable interface else object is going to throw CloneNotSupportedException when the clone method is called.
- Second the object needs to make the clone() method public.
- Next in the clone method call the super.clone()
- You need not do anything special for primitive data types, its wrapper objects and immutable objects like String, the super.clone() method automatically creates a copy of them.
- When you perform a deep copy involving collections the objects in the collection also needs to implement Cloneable.
Problems with cloning
- The entire object graph needs to be cloned, which is tiresome and error prone and difficult to maintain. Care should be taken when there is a modification to the classes.
- Care should also be taken in circular reference of object, the reference object should be created only once. Ex Say Department contains Employee class and Employee inturn refers Department, care should be taken that the reference department is created only once.
- If the class is not available for modification (third party classes), and there is a need for cloning, you need to create a new class by sub-classing and then overriding the clone method.
- Also its problematic to clone a polymorphic variable, as the decision has to wait till the runtime.
Alternatives to cloning
Java Serialization offers an alternative for cloning (key here is the object and all the referenced objects needs to be serializable), here the entire object tree is traversed and serialized, and de-serializing it later will yield the exact state but a different copy of the original serialized object. However the cost of serialization is its performance, as this involves writing and reading from the stream.