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

我想知道是否有推荐的方法在java中做深层克隆/副本实例。

我有三个解决方案,但我可能会错过一些,我想听听你的意见

编辑:包括Bohzo提议和改进问题:关于深克隆更多的是浅层克隆。

自己做:

在属性之后用手属性编码克隆并检查可变实例是否被克隆。
亲们:
- 控制将要执行的操作
- 快速执行
缺点:
- 繁琐的编写和维护
- 容易出错(复制/粘贴失败,缺少属性,重新分配可变属性)

使用反射:

使用自己的反射工具或外部助手(如jakarta common-beans),编写通用复制方法很容易,该方法将在一行中完成这项工作。
亲们:
- 易于编写
- 没有维护
缺点:
- 对发生什么的控制较少
- 如果反射工具不克隆子对象,则易受易变对象影响
- 执行速度较慢

使用克隆框架:

使用一个可以为你做的框架,比如:
commons-lang SerializationUtils
Java深度克隆库
推土机
KRYO

亲们:
- 和反射一样
- 更多地控制将要被克隆的东西。
缺点:
- 每个可变实例都被完全克隆,即使在层次结束时也是如此
- 执行速度可能非常慢

使用字节码工具在运行时编写克隆

javassit,BCEL或cglib可能会用于单手编写一个专用克隆器。 有人知道使用这些工具之一为此目的的lib吗?

我在这里错过了什么?
你会推荐哪一个?

谢谢。


对于深度克隆(克隆整个对象层次结构):

  • commons-lang SerializationUtils - 使用序列化 - 如果所有类都在您的控制之下,并且您可以强制执行Serializable

  • Java深度克隆库 - 使用反射 - 在您想要克隆的类或对象超出您的控制范围(第三方库)的情况下,并且您无法让它们实现Serializable ,或者您不希望实现Serializable

  • 对于浅层克隆(克隆只有一级属性):

  • commons-beanutils BeanUtils - 在大多数情况下。

  • Spring BeanUtils - 如果你已经在使用spring,并且在类路径中有这个实用工具。

  • 我故意省略了“自己动手”选项 - 上面的API提供了一个很好的控制什么和什么不克隆(例如使用transientString[] ignoreProperties ),所以重新发明轮子不是首选。


    Joshua Bloch的这本书有一章,题目为“第10条:明智地重申克隆”,他在其中深入探讨了为什么压倒性的克隆大部分是一个坏主意,因为Java的规范带来了很多问题。

    他提供了几个选择:

  • 使用工厂模式代替构造函数:

         public static Yum newInstance(Yum yum);
    
  • 使用复制构造函数:

         public Yum(Yum yum);
    
  • Java中的所有集合类都支持复制构造函数(例如,新的ArrayList(l);)


    自2.07版以来,Kryo支持浅层/深层克隆:

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

    Kryo速度很快,在他们的页面上你可以找到一份在生产中使用它的公司名单。

    链接地址: http://www.djcxy.com/p/40793.html

    上一篇: Java: recommended solution for deep cloning/copying an instance

    下一篇: Storing Names in ArrayList and Using it to Login