为了账号安全,请及时绑定邮箱和手机立即绑定

深度克隆实用程序推荐

深度克隆实用程序推荐

哆啦的时光机 2019-08-31 14:46:16
是否有任何用于深度克隆java集合的实用程序:数组清单地图注意:在不使用序列化的情况下更喜欢某些解决方案,但使用Object.clone()方法。我可以肯定我的自定义对象将实现clone()方法,并将只使用可克隆的java标准类...
查看完整描述

3 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

在Java中复制对象的所有方法都有严重的缺陷:


克隆


clone()方法受到保护,因此除非有问题的类使用公共方法覆盖它,否则不能直接调用它。

clone()不会调用构造函数。任何构造函数。它将分配内存,分配内部class字段(您可以通过其读取getClass())并复制原始字段。

有关clone()的更多问题,请参阅Joshua Bloch的书“ Effective Java,Second Edition ”的第11项


连载


序列化更糟糕; 它有许多缺点,clone()然后有一些缺陷。约书亚有一整章只有四个项目。


我的解决方案


我的解决方案是为我的项目添加一个新界面:


public interface Copyable<T> {

    T copy ();

    T createForCopy ();

    void copyTo (T dest);

}

代码如下所示:


class Demo implements Copyable<Demo> {

    public Demo copy () {

        Demo copy = createForCopy ();

        copyTo (copy);

        return copy;

    }

    public Demo createForCopy () {

        return new Demo ();

    }

    public void copyTo (Demo dest)

        super.copyTo (dest);

        ...copy fields of Demo here...

    }

}

不幸的是,我必须将此代码复制到我的所有对象,但它始终是相同的代码,因此我可以使用Eclipse编辑器模板。好处:


我可以决定调用哪个构造函数以及如何初始化哪个字段。

初始化以确定性顺序发生(根类到实例类)

我可以重用现有的对象并覆盖它们

输入安全

单身人士留着单身人士

对于标准Java类型(如集合等),我使用可以复制它们的实用程序类。这些方法有标记和回调,所以我可以控制副本的深度。


查看完整回答
反对 回复 2019-08-31
?
慕后森

TA贡献1802条经验 获得超5个赞

浅克隆的集合是很容易的,但如果你想深克隆,图书馆可能会做你比手更好的编码它(因为要克隆的元素里面集合为好)。


就像这个答案一样,我使用了Cloner库,并专门针对XStream进行了性能测试(可以通过序列化然后反序列化来克隆')和二进制序列化。虽然XStream在向/从xml序列化方面非常快,但克隆在克隆方面要快得多:


0.0851 ms:xstream(通过序列化/反

序列化克隆)0.0223 ms:二进制序列化(通过序列化/反序列化克隆)

0.0017 ms:cloner 

* 克隆一个简单对象(两个字段)的平均时间,没有默认的公共构造函数。运行10,000次。


除了快速,这里有更多选择克隆人的理由:


执行任何对象的深度克隆(即使是那些你自己不写的对象)

每次添加字段时,都不必使clone()方法保持最新

您可以克隆没有默认公共构造函数的对象

适用于Spring

(优化)不克隆已知的不可变对象(如Integer,String等)

使用方便。例:


cloner.deepClone(anyObject);


查看完整回答
反对 回复 2019-08-31
  • 3 回答
  • 0 关注
  • 417 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号