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类型(如集合等),我使用可以复制它们的实用程序类。这些方法有标记和回调,所以我可以控制副本的深度。

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);
添加回答
举报