Java: recommended solution for deep cloning/copying an instance
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.
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.
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 (eg new ArrayList(l);)
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.
链接地址: http://www.djcxy.com/p/40794.html上一篇: 克隆对象的值更改时,原始对象也会更改