在java中可以使用多少种类型的克隆对象?

时间:2011-04-01 08:51:15

标签: java

java中有多少种类型的克隆对象?

4 个答案:

答案 0 :(得分:9)

两种类型的克隆

阅读Bozho的回答 java-recommended-solution-for-deep-cloning-copying-an-instance

faster deep copies

上的一些有趣主题

浅克隆

  

它是对象的逐位副本。一个   创建具有的新对象   完全复制的值   原始物体。如果有任何字段   该对象的引用是对其他的引用   对象,只是引用   复制。因此,如果你是对象   复制包含对引用的引用   其他对象,浅拷贝指   对于相同的子对象。

深度克隆。

  

深层复制是完整的副本   一个对象。如果一个对象有   对其他对象的引用,完整   这些对象的新副本也是   制作。深拷贝不会生成副本   只有原始值的   原始对象,但所有副本   次要对象,一直到   底部。如果你需要一个真实的,完整的   原始对象的副本,然后你   将需要实施一个完整的深度   复制对象。

     

Java支持浅层和深层复制   用Cloneable接口来创建   对象的副本。做一个克隆   一个Java对象,你声明一个   object实现Cloneable,然后   提供克隆的覆盖   标准Java对象的方法   基类。实现Cloneable   告诉java编译器你的   对象是Cloneable。克隆是   实际上是由克隆方法完成的。

创建对象的方式有多少。

  • 序列化
  • clone()方法
  • new operator copy constructor。

答案 1 :(得分:1)

浅拷贝

通常克隆对象的方法,创建同一个类的新实例,并将所有字段复制到新实例并返回它。这只不过是浅色的副本。 Object类提供克隆方法并为浅拷贝提供支持。它返回'Object'作为类型,您需要显式地转换回原始对象。

由于Object类具有clone方法(受保护),因此无法在所有类中使用它。要克隆的类应该实现克隆方法并覆盖它。它应该为复制提供它自己的含义,或者至少它应该调用super.clone()。此外,您必须实现Cloneable标记接口,否则您将获得CloneNotSupportedException。当你调用super.clone()时,你依赖于Object类的实现,你得到的是一个浅表副本。

深层复制

当您需要深层复制时,您需要自己实施。当复制的对象包含某些其他对象时,其引用将以深层副本的形式递归复制。当您实现深拷贝时要小心,因为您可能会因为循环依赖而陷入困境。如果您不想自己实施深层复制,那么您可以进行序列化。它确实实现了深层复制,隐式地和优雅地处理循环依赖。

这个克隆系统的另一个缺点是,java中的大多数接口/抽象类编写器都忘了放置一个公共克隆方法。例如,您可以使用List。因此,当您想要克隆它们的实现时,您必须忽略抽象类型并按名称使用ArrayList之类的实际实现。这完全消除了抽象性的优点和优点。

实现单例模式时,如果其超类实现了一个公共clone()方法,那么为了防止你的子类使用这个类的clone()方法来获取一个副本来覆盖它并抛出一个CloneNotSupportedException类型的异常。

请注意,clone不适用于实例化和初始化。它不应该同义地用作创建新对象。因为克隆对象的构造函数可能永远不会在进程中被调用。它是关于在讨论中复制对象而不是创建新对象。它完全取决于克隆实现。还有一个缺点(如何处理这么多),克隆阻止使用最终字段。我们必须找到将最终字段复制到复制对象中的迂回方式。

克隆是您,编译器和实现者之间的协议。如果您确信这三个人都对java有很好的了解,那么请继续使用clone。如果您有任何疑问,可以手动复制对象。

答案 2 :(得分:0)

一种方法是实现Cloneable。

或者你可以根据你的要求选择deepCopy或shalowCopy。

答案 3 :(得分:0)

您的问题提出的“明显”答案是实施Cloneable界面并覆盖Object.clone()。但是,this API is obsolete and broken因此不应在新代码中使用。

可能最好 - 最“主流”,因此最容易理解和使用 - 方式是实现复制构造函数

当然,人们可以使用深层或浅层副本,以他喜欢的任何名称实现完全自定义 - 静态或非静态 - 克隆方法。只是这将不那么惯用,因此更难学习和使用,所以不建议这样做。