我们使用序列化实现了通用的深层复制机制。
import java.io.*;
public class CopyUtil {
public static Object clone(Object source) {
Object retVal = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(source);
oos.flush();
oos.close();
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
retVal = in.readObject();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return retVal;
}
}
有相对大量的对象类,它们一直在不断发展,需要维护 - 这就是我们继续使用通用克隆机制的原因。我们并不喜欢在200多个课程上维护readObject()
和writeObject()
的想法。
不幸的是,Java中的序列化机制相对较慢,当我们的系统处于峰值负载时,我们遇到了问题。
是否有任何建议的方法可以解决我们如何加速某些事情或(如果我们错误地执行此操作)克隆对象的替代方法?
答案 0 :(得分:6)
在Hibernate中实现了更快的序列化替代方法(特别是在二级缓存中);我不知道详细信息,但您可以查看源代码。
你可能知道clone()
接口被破坏了,因此最好避免使用它,除非有一个非常有说服力的理由使用它。从Effective Java 2nd Edition开始,第11项:明智地覆盖克隆
考虑到与
Cloneable
相关的所有问题,可以肯定地说 其他接口不应该扩展它,以及那些为继承而设计的类 (第17项)不应实施。一些因为它有许多缺点 专家程序员只需选择永不覆盖clone
方法,永远不要 调用它,可能除了复制数组。如果你设计一个继承类, 请注意,如果您选择不提供表现良好的受保护clone
方法,子类不可能实现Cloneable
。
创建并返回此对象的副本。 “复制”的确切含义可能取决于对象的类别。 [...]
按照惯例,此方法返回的对象应独立于此对象(正在克隆)。要实现此独立性,可能需要在返回之前修改super.clone返回的对象的一个或多个字段。通常,这意味着复制包含被克隆对象的内部“深层结构”的任何可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含原始字段或对不可变对象的引用,那么通常需要修改super.clone返回的对象中的任何字段。
事实上,惯例是做一个深层复制。
但是,首选的替代方法是定义复制构造函数或独立方法,而不是覆盖clone()
。
答案 1 :(得分:2)
您可能需要查看Deep Cloning Library。我不知道它是如何实现的,但你可能会发现它是一个更快的解决方案。
虽然它没有解决速度问题,this question有一些值得研究的相关资源。