当前位置: 首页 > 面试题库 >

加快Java深度复制操作

笪德华
2023-03-14
问题内容

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

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;
    }
}

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

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

是否有任何建议的方法可以加快速度,或者(如果执行不正确的话)克隆对象的替代方法


问题答案:

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

您可能知道clone()接口已损坏,因此最好避免使用,除非有确实令人信服的理由使用它。摘自Effective Java 2nd
Edition
,第11条: 明智地覆盖克隆

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

更新:浅/深克隆

从clone()API中:

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

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

因此,实际上,惯例是进行深层复制。

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



 类似资料:
  • 问题内容: 我正在尝试复制嵌套列表,但是 不 使用该函数不知道该如何做。 我用了: 和 但事实证明,它们全都是浅表。 有什么提示吗? 问题答案: 我的模拟输入: 策略:遍历传入对象的每个元素,递归地下降到也可迭代的元素中,并创建相同类型的新对象。 无论它是全面的还是没有错误的,我都不会提出任何主张[1](不要传递引用自己的对象!),但是应该让您入门。 [1]真的!这里的重点是演示,而不是涵盖所有可

  • 问题内容: 我正在使用。我想将对象的值复制到另一个对象中。我尝试用encoding / gob和encoding / json做到这一点。但是gob编码比json编码花费更多的时间。我看像其他一些问题,这和他们建议采空区编码应该是更快的。但我看到完全相反的行为。有人可以告诉我我做错了什么吗?还是有比这两个更好,更快的方法来进行深度复制?我的对象的结构是复杂且嵌套的。 测试代码: 我得到以下输出:

  • 问题内容: 我有一个带有Node的图类,其中每个Node可以连接到其他节点: 我想复制整个图。第一次尝试,我尝试制作一个类似以下的复制构造函数: 因此,深度复制图形将是: 但这不起作用,因为这破坏了节点之间的连接关系。我想知道是否有人建议以一种简单的方式做到这一点?谢谢。 问题答案: 问题是您需要复制节点的身份,而不仅仅是节点的值。具体来说,当您复制某个节点时,您需要处理其所指节点的身份。这意味着

  • 问题内容: 我想知道是否需要避免在创建一个带有嵌入式对象数组的简单对象时复制对对象的引用。情况如下:我有一个接受JSON并应用一些逻辑然后将对象存储在其中的服务器D B。可以说,我的表单用于保存DB中的团队。服务器接受team作为json。团队有一个TeamMember对象数组,我的表单有一个简单的字段来输入团队成员信息并将其添加到团队teamMembers数组中。现在这是一个问题,当我向数组列表

  • 问题 你想复制一个对象,包含其所有子对象。 解决方案 clone = (obj) -> if not obj? or typeof obj isnt 'object' return obj if obj instanceof Date return new Date(obj.getTime()) if obj instanceof RegExp flags

  • 编辑:@Rohit Jain 我的Recipe类和Ingreatent类(Recipe数组保存的对象)都有toString方法和recipes对Ingreats的调用,以便以一个漂亮的小格式将其全部打印出来。当我在我的“recipeone”对象(即意大利辣香肠披萨)上调用它时,我得到的是“意大利辣香肠披萨:1.0磅面团,8.0盎司酱汁,10.0盎司奶酪”。 然后我继续制作对象ressippi并将其