Java:深度克隆/复制实例的推荐解决方案
我想知道是否有推荐的方法在 Java 中进行实例的深度克隆/复制.
I'm wondering if there is a recommended way of doing deep clone/copy of instance in java.
我有 3 个解决方案,但我可能会错过一些,我想听听您的意见
I have 3 solutions in mind, but I can have miss some, and I'd like to have your opinion
包括 Bohzo 命题并改进问题:它更多地是关于深克隆而不是浅克隆.
edit: include Bohzo propositon and refine question: it's more about deep cloning than shallow cloning.
在属性之后手动对克隆进行编码,并检查是否也克隆了可变实例.
专业:
- 控制将要执行的操作
- 快速执行
缺点:
- 编写和维护繁琐
- 容易出错(复制/粘贴失败、缺少属性、重新分配可变属性)
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)
使用您自己的反射工具或外部帮助程序(如 jakarta common-beans),很容易编写一个通用的复制方法,该方法将在一行中完成工作.
专业:
- 易于编写
- 无需维护
缺点:
- 减少对发生的事情的控制
- 如果反射工具也没有克隆子对象,则可变对象容易出错
- 执行速度较慢
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
使用适合您的框架,例如:
commons-lang序列化实用程序
Java 深度克隆库
推土机
Kryo
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
javassit、BCEL 或 cglib 可用于生成专用克隆器像一只手写的一样快.有人知道为此目的使用这些工具之一的库吗?
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 ?
谢谢.
对于深度克隆(克隆整个对象层次结构):
-
commons-lang SerializationUtils - 使用序列化 - 如果所有类都在你的控制之下,你可以强制实现
Serializable
.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 深度克隆库 - 使用反射 - 在类或对象的情况下您想要克隆不受您的控制(第 3 方库)并且您不能让它们实现
Serializable
,或者在您不想实现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
.commons-beanutils BeanUtils - 在大多数情况下.
commons-beanutils BeanUtils - in most cases.
Spring BeanUtils - 如果你已经在使用 spring,因此在类路径上有这个实用程序.
Spring BeanUtils - if you are already using spring and hence have this utility on the classpath.
我故意省略了自己动手"选项 - 上面的 API 提供了对克隆什么和不克隆什么的良好控制(例如使用
transient
或String[] ignoreProperties
),所以重新发明轮子不是首选.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.
-