加快java深层复制操作

Pra*_*ram 5 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

存在相对大量的对象类,它们一直在不断发展,需要维护 - 这就是我们继续使用通用克隆机制的原因.我们没有保持津津乐道的想法readObject(),并writeObject()在200多个班.

不幸的是,Java中的序列化机制相对较慢,当我们的系统处于峰值负载时,我们遇到了问题.

是否有任何建议的方法可以让我们如何加快速度或者(如果我们错误地执行了这一点)克隆对象的替代方法?

Pét*_*rök 6

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

你可能知道clone()接口坏了,因此最好避免使用它,除非有一个真正令人信服的理由使用它.从Effective Java 2nd Edition,第11项:明智地覆盖克隆

鉴于所有与之相关的问题Cloneable,可以肯定地说其他接口不应该扩展它,并且为继承而设计的类(第17项)不应该实现它.由于它有许多缺点,一些专家程序员只是选择永远不要覆盖clone方法,永远不要调用它,除非复制数组.如果您设计了一个继承类,请注意,如果您选择不提供行为良好的受保护clone 方法,则子类将无法实现Cloneable.

更新:浅/深克隆

来自clone()API:

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

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

所以事实上,惯例是做一个深层复制.

尽管如此,首选的替代方法是定义复制构造函数或独立方法,而不是重写clone().

  • @Bozho,默认实现,是的. (2认同)