加快java深层复制操作

时间:2010-09-02 12:26:43

标签: java performance serialization

我们使用序列化实现了通用的深层复制机制。

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中的序列化机制相对较慢,当我们的系统处于峰值负载时,我们遇到了问题。

是否有任何建议的方法可以解决我们如何加速某些事情或(如果我们错误地执行此操作)克隆对象的替代方法?

2 个答案:

答案 0 :(得分:6)

Hibernate中实现了更快的序列化替代方法(特别是在二级缓存中);我不知道详细信息,但您可以查看源代码。

你可能知道clone()接口被破坏了,因此最好避免使用它,除非有一个非常有说服力的理由使用它。从Effective Java 2nd Edition开始,第11项:明智地覆盖克隆

  

考虑到与Cloneable相关的所有问题,可以肯定地说   其他接口不应该扩展它,以及那些为继承而设计的类   (第17项)不应实施。一些因为它有许多缺点   专家程序员只需选择永不覆盖clone方法,永远不要   调用它,可能除了复制数组。如果你设计一个继承类,   请注意,如果您选择不提供表现良好的受保护clone   方法,子类不可能实现Cloneable

更新:浅层/深层克隆

来自the clone() API

  

创建并返回此对象的副本。 “复制”的确切含义可能取决于对象的类别。 [...]

     

按照惯例,此方法返回的对象应独立于此对象(正在克隆)。要实现此独立性,可能需要在返回之前修改super.clone返回的对象的一个​​或多个字段。通常,这意味着复制包含被克隆对象的内部“深层结构”的任何可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含原始字段或对不可变对象的引用,那么通常需要修改super.clone返回的对象中的任何字段。

事实上,惯例是做一个深层复制。

但是,首选的替代方法是定义复制构造函数或独立方法,而不是覆盖clone()

答案 1 :(得分:2)

您可能需要查看Deep Cloning Library。我不知道它是如何实现的,但你可能会发现它是一个更快的解决方案。

虽然它没有解决速度问题,this question有一些值得研究的相关资源。