public static Object deepClone(Object object) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
2)
// (1) create a MyPerson object named Al
MyAddress address = new MyAddress("Vishrantwadi ", "Pune", "India");
MyPerson al = new MyPerson("Al", "Arun", address);
// (2) make a deep clone of Al
MyPerson neighbor = (MyPerson)deepClone(al);
20条答案
按热度按时间rjee0c151#
对于spring框架用户。使用类
org.springframework.util.SerializationUtils
:w51jfk4q2#
我用dozer克隆java对象,这很好,kryo库是另一个很好的选择。
slmsl1lt3#
深度复制只能在每个班级同意的情况下进行。如果可以控制类层次结构,则可以实现clonable接口和clone方法。否则,由于对象也可能共享非数据资源(例如数据库连接),因此无法安全地执行深度复制。但是,在java环境中,深度复制通常被认为是不好的做法,应该通过适当的设计实践来避免。
nzrxty8p4#
apachecommons提供了一种深度克隆对象的快速方法。
nkkqxpd95#
实现深度复制的一种方法是向每个关联的类添加复制构造函数。复制构造函数将“this”的一个示例作为其单个参数,并从中复制所有值。相当多的工作,但相当直接和安全。
编辑:请注意,不需要使用访问器方法来读取字段。您可以直接访问所有字段,因为源示例的类型始终与使用复制构造函数的示例的类型相同。显而易见,但可能被忽视。
例子:
编辑:请注意,当使用复制构造函数时,您需要知道要复制的对象的运行时类型。使用上述方法,您无法轻松地复制混合列表(您可以使用一些反射代码来实现这一点)。
lsmd5eda6#
小豆子在克隆豆子方面做得很好。
ou6hu8tu7#
xstream在这种情况下非常有用。下面是一个简单的克隆代码
mnowg1ta8#
对于复杂的对象,当性能不显著时,我使用json库(比如gson)将对象序列化为json文本,然后反序列化文本以获得新对象。
基于反射的gson在大多数情况下都是有效的,除了
transient
不会复制字段和有原因的循环引用对象StackOverflowError
.gzjq41n49#
下面是一个通用的深度克隆方法,它使用对象序列化和字节数组流的反序列化(以避免写入文件)。
brgchamk10#
使用xstream(http://x-stream.github.io/). 甚至可以通过注解或显式指定xstream类的属性名来控制可以忽略哪些属性。此外,您不需要实现可关闭的接口。
qojgxg4l11#
在这里,myperson和myaddress类必须实现serializable接口
a5g8bdjr12#
您可以使用具有简单api的库,并使用反射执行相对快速的克隆(应该比序列化方法快)。
gajydyqb13#
一种非常简单的方法是使用jacksonjson将复杂的java对象序列化为json并读回。
从https://github.com/fasterxml/jackson-databind/#5-分钟教程流解析生成器:
0yycz8jy14#
使用jackson序列化和反序列化对象。此实现不需要对象来实现可序列化类。
hwazgwia15#
有几个人提到使用或重写
Object.clone()
. 别这么做。Object.clone()
有一些主要问题,在大多数情况下不鼓励使用。请参阅joshua bloch的“effective java”中的第11项,以获得完整的答案。我相信你可以安全使用Object.clone()
但除此之外,您还需要明智地正确使用和重写克隆。依赖于序列化(xml或其他)的方案是笨拙的。
这里没有简单的答案。如果要深度复制对象,则必须遍历对象图并通过对象的复制构造函数或静态工厂方法显式复制每个子对象,而静态工厂方法反过来又深度复制子对象。不可变(例如。
String
s) 不需要复制。另外,出于这个原因,您应该支持不变性。