I'm wondering if there is a recommended way of doing deep clone/copy of instance in java.
I have 3 solutions in mind, but I can have miss some, and I'd like to have your opinion
edit: include Bohzo propositon and refine question: it's more about deep cloning than shallow cloning.
Do it yourself:
code the clone by hand properties after properties and check that mutable instances are cloned too.
pro:
– control of what will be performed
– quick execution
cons:
– tedious to write and maintain
– bug prone (copy/paste failure, missing property, reassigned mutable property)
Use reflection:
With your own reflection tools or with an external helper (like jakarta common-beans) it is easy to write a generic copy method that will do the job in one line.
pro:
– easy to write
– no maintenance
cons:
– less control of what happens
– bug prone with mutable object if the reflection tool does not clone sub objects too
– slower execution
Use clone framework:
Use a framework that do it for you, like :
commons-lang SerializationUtils
Java Deep Cloning Library
Dozer
Kryo
pro:
– same as reflection
– more control over what will be exactly be cloned.
cons:
– every mutable instance is fully cloned, even at the end of the hierarchy
– could be very slow to execute
Use bytecode instrumentation to write clone at runtime
javassit, BCEL or cglib might be use to generate a dedicated cloner as fast as one hand writed. Someone knows a lib using one of these tools for this purpose ?
What I have missed here ?
Which one would you recommend ?
Thanks.
Best Answer
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 implementSerializable
.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
, orString[] ignoreProperties
), so reinventing the wheel isn't preferred.