中的clone
操作ArrayList
返回对象的浅拷贝,并且不适合您的目的。手动解决方法是:
- 创建与源列表大小相同的目标数组列表
- 迭代源列表并将每个项目的克隆创建到目标列表中
显然,这仅在数组列表包含实现clone
的项目时才有效,并且项目clone
操作实际上返回一个深层副本。换句话说,它不能保证。实际上,为 Java 对象实现深度克隆功能并不容易,请参阅Java 中的广泛讨论:深度克隆/复制实例和其他 SO 线程的推荐解决方案,以了解可用选项。除了那里提供的答案外,还有其他一些选项:
序列化
如果层次结构中的所有(必需的)对象都可以序列化,那么您可以使用这个简单的代码进行深度克隆:
public MyGraph deepCopy() {
try {
final ByteArrayOutputStream baos = new ByteArrayOutputStream(256);
final ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();
final ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray()));
final MyGraph clone = (QuicksortTest) ois.readObject();
return clone;
} catch (final Exception e) {
throw new RuntimeException("Cloning failed");
}
}
请注意,一些深度克隆库将标准 Java 序列化与反射黑客和/或字节码检测结合起来,以使整个对象层次结构完全可序列化。您可能需要,也可能不需要。
复制工具
例如,Dozer提供快速的深拷贝功能。Orika也可以达到相同的效果,尽管需要更多配置:
public MyGraph deepCopy() {
final DozerBeanMapper mapper = new DozerBeanMapper();
final QuicksortTest clone = mapper.map(this, MyGraph.class);
return clone;
}
当然,唯一的缺点是您需要将额外的依赖项拉入您的项目。
总而言之,您的deepCopy
方法不应该是静态的。此外,您应该认真考虑通过将对象的状态设为私有并实现 getter/setter 来封装对象的状态。