Clone() vs Copy 构造函数 - 在 java 中推荐
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2427883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Clone() vs Copy constructor- which is recommended in java
提问by Jothi
clone method vs copy constructor in java. which one is correct solution. where to use each case?
java中的克隆方法与复制构造函数。哪个是正确的解决方案。在哪里使用每个案例?
采纳答案by Tom
Clone is broken, so dont use it.
克隆坏了,所以不要使用它。
THE CLONE METHOD of the Object class is a somewhat magical method that does what no pure Java method could ever do: It produces an identical copy of its object. It has been present in the primordial Object superclass since the Beta-release days of the Java compiler*; and it, like all ancient magic, requires the appropriate incantation to prevent the spell from unexpectedly backfiring
Object 类的克隆方法是一种有点神奇的方法,它可以完成纯 Java 方法永远无法做到的事情:它生成其对象的相同副本。自 Java 编译器的 Beta 版发布以来,它就一直存在于原始 Object 超类中*;和所有古代魔法一样,它需要适当的咒语来防止法术意外适得其反
Prefer a method that copies the object
更喜欢复制对象的方法
Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}
Read more http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx
阅读更多 http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx
回答by Bozho
Have in mind that clone()
doesn't work out of the box. You will have to implement Cloneable
and override the clone()
method making in public
.
请记住,clone()
这不是开箱即用的。你将不得不实施Cloneable
并重写clone()
的方法制作public
。
There are a few alternatives, which are preferable (since the clone()
method has lots of design issues, as stated in other answers), and the copy-constructor would require manual work:
有一些替代方案,它们是可取的(因为该clone()
方法有很多设计问题,如其他答案所述),并且复制构造函数需要手动工作:
BeanUtils.cloneBean(original)
creates a shallow clone, like the one created byObject.clone()
. (this class is from commons-beanutils)SerializationUtils.clone(original)
creates a deep clone. (i.e. the whole properties graph is cloned, not only the first level) (from commons-lang), but all classes must implementSerializable
Java Deep Cloning Libraryoffers deep cloning without the need to implement
Serializable
BeanUtils.cloneBean(original)
创建一个浅克隆,就像由Object.clone()
. (这个类来自commons-beanutils)SerializationUtils.clone(original)
创建一个深度克隆。(即整个属性图被克隆,不仅是第一级)(来自commons-lang),但所有类都必须实现Serializable
Java Deep Cloning Library提供无需实现的深度克隆
Serializable
回答by polygenelubricants
See also: How to properly override clone method?. Cloning is broken in Java, it's so hardto get it right, and even when it does it doesn't really offer much, so it's not really worth the hassle.
另请参阅:如何正确覆盖克隆方法?. 克隆在 Java 中被破坏了,很难做到正确,即使这样做了,它也没有真正提供多少,所以它真的不值得麻烦。
回答by Steve Kuo
Keep in mind that the copy constructor limits the class type to that of the copy constructor. Consider the example:
请记住,复制构造函数将类类型限制为复制构造函数的类型。考虑这个例子:
// Need to clone person, which is type Person
Person clone = new Person(person);
This doesn't work if person
could be a subclass of Person
(or if Person
is an interface). This is the whole point of clone, is that it can can clone the proper type dynamically at runtime (assuming clone is properly implemented).
如果person
可能是Person
(或者如果Person
是接口)的子类,则这不起作用。这就是 clone 的全部意义所在,它可以在运行时动态地克隆正确的类型(假设正确实现了 clone)。
Person clone = (Person)person.clone();
or
或者
Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer
Now person
can be any type of Person
assuming that clone
is properly implemented.
现在person
可以是正确实施的任何类型的Person
假设clone
。
回答by Rose Perrone
clone() was designed with several mistakes (see this question), so it's best to avoid it.
clone() 的设计有几个错误(参见这个问题),所以最好避免它。
From Effective Java 2nd Edition, Item 11: Override clone judiciously
来自Effective Java 2nd Edition,第 11 条:明智地覆盖克隆
Given all of the problems associated with Cloneable, it's safe to say that other interfaces should not extend it, and that classes designed for inheritance (Item 17) should not implement it. Because of its many shortcomings, some expert programmers simply choose never to override the clone method and never to invoke it except, perhaps, to copy arrays. If you design a class for inheritance, be aware that if you choose not to provide a well-behaved protected clone method, it will be impossible for subclasses to implement Cloneable.
鉴于与 Cloneable 相关的所有问题,可以肯定地说其他接口不应该扩展它,并且设计用于继承的类(条目 17)不应该实现它。由于它的许多缺点,一些专家程序员只是选择从不覆盖 clone 方法并且从不调用它,除非可能复制数组。如果您为继承设计类,请注意,如果您选择不提供行为良好的受保护的克隆方法,子类将无法实现 Cloneable。
This book also describes the many advantages copy constructors have over Cloneable/clone.
本书还描述了复制构造函数相对于 Cloneable/clone 的许多优点。
- They don't rely on a risk-prone extralinguistic object creation mechanism
- They don't demand unenforceable adherence to thinly documented conventions
- They don't conflict with the proper use of final fields
- They don't throw unnecessary checked exceptions
- They don't require casts.
- 他们不依赖有风险的语言外对象创建机制
- 他们不要求不可强制地遵守没有记录的约定
- 它们与正确使用 final 字段不冲突
- 他们不会抛出不必要的检查异常
- 他们不需要演员表。
All standard collections have copy constructors. Use them.
所有标准集合都有复制构造函数。使用它们。
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
回答by Roboprog
Great sadness: neither Cloneable/clone nor a constructor are great solutions: I DON'T WANT TO KNOW THE IMPLEMENTING CLASS!!! (e.g. - I have a Map, which I want copied, using the same hidden MumbleMap implementation) I just want to make a copy, if doing so is supported. But, alas, Cloneable doesn't have the clone method on it, so there is nothing to which you can safely type-cast on which to invoke clone().
非常遗憾:Cloneable/clone 和构造函数都不是很好的解决方案:我不想知道实现类!!!(例如 - 我有一个地图,我想复制它,使用相同的隐藏 MumbleMap 实现)我只想制作一个副本,如果支持的话。但是,唉,Cloneable 上没有 clone 方法,因此您无法安全地对其进行类型转换以调用 clone()。
Whatever the best "copy object" library out there is, Oracle should make it a standard component of the next Java release (unless it already is, hidden somewhere).
无论最好的“复制对象”库是什么,Oracle 都应该使它成为下一个 Java 版本的标准组件(除非它已经存在,隐藏在某处)。
Of course, if more of the library (e.g. - Collections) were immutable, this "copy" task would just go away. But then we would start designing Java programs with things like "class invariants" rather than the verdammt "bean" pattern (make a broken object and mutate until good [enough]).
当然,如果更多的库(例如 - 集合)是不可变的,这个“复制”任务就会消失。但随后我们将开始使用诸如“类不变量”之类的东西来设计 Java 程序,而不是使用 verdammt 的“bean”模式(制作一个损坏的对象并进行变异直到[足够好])。