Java: recommended solution for deep cloning/copying an instance

For deep cloning (clones the entire object hierarchy):

  • commons-lang SerializationUtils - using serialization - if all classes are in your control and you can force implementing Serializable.

  • Java Deep Cloning Library - using reflection - in cases when the classes or the objects you want to clone are out of your control (a 3rd party library) and you can't make them implement Serializable, or in cases you don't want to implement Serializable.

For shallow cloning (clones only the first level properties):

  • commons-beanutils BeanUtils - in most cases.

  • Spring BeanUtils - if you are already using spring and hence have this utility on the classpath.

I deliberately omitted the "do-it-yourself" option - the API's above provide a good control over what to and what not to clone (for example using transient, or String[] ignoreProperties), so reinventing the wheel isn't preferred.


Since version 2.07 Kryo supports shallow/deep cloning:

Kryo kryo = new Kryo();
SomeClass someObject = ...
SomeClass copy1 = kryo.copy(someObject);
SomeClass copy2 = kryo.copyShallow(someObject);

Kryo is fast, at the and of their page you may find a list of companies which use it in production.


Joshua Bloch's book has a whole chapter entitled "Item 10: Override Clone Judiciously" in which he goes into why overriding clone for the most part is a bad idea because the Java spec for it creates many problems.

He provides a few alternatives:

  • Use a factory pattern in place of a constructor:

         public static Yum newInstance(Yum yum);
    
  • Use a copy constructor:

         public Yum(Yum yum);
    

All of the collection classes in Java support the copy constructor (e.g. new ArrayList(l);)

Tags:

Java

Clone