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

    上一篇: 克隆对象的值更改时,原始对象也会更改

    下一篇: Java:深层克隆/复制实例的推荐解决方案