Clone() 与 Copy 构造函数——在 java 中推荐使用

发布于 2024-08-25 07:51:47 字数 47 浏览 9 评论 0原文

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

clone method vs copy constructor in java. which one is correct solution. where to use each case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

2024-09-01 07:51:47

克隆已损坏,因此请勿使用它。

Object类的克隆方法
是一种有点神奇的方法
纯 Java 方法无法做到的事情
do:它生成相同的副本
它的对象。它已经出现在
原始的 Object 超类
Java 的 Beta 发布日
编译器*;它,就像所有古代的
魔法,需要适当的
咒语以防止该咒语
没想到适得其反

喜欢复制对象的方法

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-java effective-cloning.aspx

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

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

那伤。 2024-09-01 07:51:47

请记住,clone() 不能开箱即用。您必须实现 Cloneable 并重写 public 中的 clone() 方法。

有一些更好的替代方案(因为 clone() 方法有很多设计问题,如其他答案中所述),并且复制构造函数需要手动工作:

  • < a href="http://commons.apache.org/beanutils/v1.8.2/apidocs/org/apache/commons/beanutils/BeanUtils.html" rel="noreferrer">BeanUtils.cloneBean(原始)< /code> 创建一个浅克隆,类似于 Object.clone() 创建的克隆。 (此类来自 commons-beanutils

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

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

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.

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:

郁金香雨 2024-09-01 07:51:47

clone() 的设计有几个错误(请参阅这个问题),所以它是最好避免它。

来自 Effective Java 第 2 版,第 11 项:明智地覆盖克隆

考虑到与 Cloneable 相关的所有问题,可以肯定地说
其他接口不应扩展它,并且类
为继承而设计(第 17 条)不​​应实现它。由于
它有很多缺点,一些专家程序员干脆选择不这样做
覆盖克隆方法并且永远不会调用它,除非,也许,
复制数组。如果您设计一个用于继承的类,请注意,如果
您选择不提供行为良好的受保护克隆方法,它
子类不可能实现Cloneable。

本书还描述了复制构造函数相对于 Cloneable/clone 的许多优点。

  • 它们不依赖于有风险的语言外对象创建机制
  • 它们不要求不可强制地遵守记录薄弱的约定
  • 它们不与最终字段的正确使用相冲突
  • 它们不抛出不必要的检查异常
  • 它们不需要演员表。

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

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

clone() was designed with several mistakes (see this question), so it's best to avoid it.

From Effective Java 2nd Edition, Item 11: Override clone judiciously

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.

This book also describes the many advantages copy constructors have over 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.

All standard collections have copy constructors. Use them.

List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
梦屿孤独相伴 2024-09-01 07:51:47

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

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

如果 person 可以是 Person 的子类(或者如果 Person 是一个接口),则此方法不起作用。这就是克隆的全部要点,它可以在运行时动态克隆正确的类型(假设克隆被正确实现)。

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

或者

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

现在 person 可以是任何类型的 Person ,假设 clone 已正确实现。

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 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.

挖鼻大婶 2024-09-01 07:51:47

另请参阅:如何正确覆盖克隆方法?。克隆在 Java 中被破坏了,要得到它非常困难,而且即使做到了也没有真正提供太多,所以它并不值得这么麻烦。

See also: How to properly override clone method?. Cloning is broken in Java, it's so hard to get it right, and even when it does it doesn't really offer much, so it's not really worth the hassle.

手心的温暖 2024-09-01 07:51:47

非常悲伤:Cloneable/clone 和构造函数都不是很好的解决方案:我不想知道实现类! (例如 - 我有一个地图,我想复制它,使用相同的隐藏 MumbleMap 实现)我只想制作一个副本(如果支持的话)。但是,可惜的是,Cloneable 没有clone 方法,因此您无法安全地进行类型转换来调用clone()。

无论最好的“复制对象”库是什么,Oracle 都应该将其作为下一个 Java 版本的标准组件(除非它已经存在,隐藏在某处)。

当然,如果更多的库(例如集合)是不可变的,那么这个“复制”任务就会消失。但随后我们将开始使用“类不变量”之类的东西来设计 Java 程序,而不是 verdammt“bean”模式(创建一个损坏的对象并进行变异,直到好[足够])。

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().

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).

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]).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文