克隆()与复制构造函数 – 这是在java中推荐

克隆方法vs在java复制构造函数。 哪一个是正确的解决scheme。 在哪里使用每个案例?

克隆被破坏,所以不要使用它。

Object类的CLONE方法是一种有点神奇的方法,它不会执行任何纯Java方法:它会生成一个相同的对象副本。 自从Java编译器*的beta版本发布以来,它已经存在于原始的Object超类中; 和所有古代的魔法一样,它需要适当的咒语来防止这个咒语意外的回火

优选一种复制对象的方法

 Foo copyFoo (Foo foo){ Foo f = new Foo(); //for all properties in FOo f.set(foo.get()); return f; } 

阅读更多http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx

请记住, clone()不能用于开箱即用。 你将不得不实现Cloneable并覆盖publicclone()方法。

有几个替代方法,这是可取的(因为clone()方法有很多devise问题,如其他答案中所述),复制构造函数将需要手动工作:

  • BeanUtils.cloneBean(original)创build一个浅的克隆,就像Object.clone()创build的一样。 (这个class来自commons-beanutils )

  • SerializationUtils.clone(original)创build一个深层克隆。 (即整个属性图被克隆,不仅是第一级)(来自commons-lang ),但所有的类都必须实现Serializable

  • Java深度克隆库提供了深度克隆,无需实现Serializable

克隆()的devise有几个错误(见这个问题 ),所以最好避免它。

从Effective Java 2nd Edition ,项目11:明智地重写克隆

鉴于与Cloneable相关的所有问题,可以肯定的是,其他接口不应该扩展它,而为inheritancedevise的类(Item 17)不应该实现它。 由于它的许多缺点,一些专家程序员只是简单地select不覆盖克隆方法,除非可能复制数组,否则不要调用它。 如果您devise了inheritance类,请注意,如果您select不提供行为良好的受保护的克隆方法,那么子类就不可能实现Cloneable。

本书还介绍了复制构造函数对Cloneable / clone的许多优点。

  • 他们不依赖风险倾向的超语言对象创build机制
  • 他们不要求不可强制遵守稀less的文件规定
  • 它们不会与正确使用最终字段相冲突
  • 他们不会抛出不必要的检查exception
  • 他们不需要演员。

所有的标准集合都有复制构造函数。 使用它们。

 List<Double> original = // some list List<Double> copy = new ArrayList<Double>(original); 

请记住,复制构造函数将类types限制为复制构造函数的类types。 考虑一下这个例子:

 // Need to clone person, which is type Person Person clone = new Person(person); 

如果person可能是Person的子类(或者Person是一个接口),这不起作用。 这是克隆的关键,它可以在运行时dynamic地克隆适当的types(假设clone被正确实现)。

 Person clone = (Person)person.clone(); 

要么

 Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer 

现在person可以是任何types的Person假设clone是正确实施。

另请参阅: 如何正确覆盖克隆方法? 。 Java中的克隆工作被打破了,要做到这一点很困难 ,即使这样做实际上并不能提供太多的东西 ,所以这并不值得。

非常悲伤:Cloneable / clone和构造函数都不是很好的解决scheme:我不想知道实现类! (例如 – 我有一个地图,我想要复制,使用相同的隐藏的MumbleMap实现)我只是想复制,如果这样做是支持的。 但是,唉,Cloneable没有克隆方法,所以没有什么可以安全地进行types转换来调用clone()。

不pipe最好的“拷贝对象”库是什么,Oracle都应该把它作为下一个Java版本的标准组件(除非它已经被隐藏在某处)。

当然,如果更多的图书馆(例如 – 集合)是不可变的,这个“复制”任务就会消失。 但是接下来我们将开始deviseJava程序,比如“类不变式”,而不是“破坏性”的“bean”模式(创build一个破损的对象,直到变得足够好)。