Java Cloneable接口 之 是否损坏?

在Java应用程序中,即使一个类实现了Cloneable接口,我们也无法对该类进行克隆。这本身就说明了Java中克隆行为的破坏。在这篇文章中,我将探讨其他原因。

Java克隆中,我们讨论了创建Java对象克隆的各种方法,包括浅层和深层克隆复制构造函数以及一些最佳实践。现在让我们讨论一下Cloneable接口之间的差距。

目录

如何克隆接口?
专家说
Java复制最佳做法

Java Cloneable接口如何制动?

  1. 第一个差距是clone()方法应该位于Cloneable接口中。如果实现Cloneable接口(不要重写clone()方法),则它不会在运行时影响类中的任何事物。实际上,如果A类实现Cloneable,则默认行为应该已经存在,那么某人应该能够做到这一点:
    //Ideal behavior; Cloneable should have been implemented like this
    
    class A implements Cloneable
    {
    	//member attributes and methods
    }
    
    class B
    {
    	A a = new A();
    	if(a instanceof Cloneable)
    	{
    		A copied = a.clone(); //I should be able to do this; But I am not.
    	}
    }
    
  2. clone()方法不会调用任何构造函数来创建新实例,这使其成为构造函数的另一种变体,其行为不在我们的控制范围内。换句话说:“ 克隆调用了一种构造对象的语言外方法,即没有构造函数 ”。
  3. 除了上述事实以外,它也是拼写错误经典示例。正确的拼写应该是“可克隆的 ”。
  4. Java中没有创建深层副本的机制。甚至在对象类之前调用​​super.clone()都会创建浅表副本。

专家对Java Cloneable接口的评价


  1. 乔希·布洛克在采访中

    “存在一些设计缺陷,其中最大的缺陷是Cloneable接口没有克隆方法。这意味着它根本行不通:制作可克隆内容并不能说明您可以使用它做什么。相反,它说明了其内部功能。它说,如果通过重复调用super.clone最终导致调用Object的clone方法,该方法将返回原始文件的字段副本。”


  2. 肯·阿诺德(Ken Arnold)的访谈

    “如果此时我要成为上帝,并且很多人可能会很高兴我不是上帝,我会说弃用Cloneable并拥有一个Copyable,因为Cloneable存在问题。除了它拼写错误的事实外,Cloneable还不包含clone方法。这意味着您无法测试某事物是否是Cloneable的实例,无法将其强制转换为Cloneable并调用克隆。您必须再次使用反射,这太糟糕了。那只是一个问题,但我肯定会解决的。”

Java复制最佳做法

正如我之前的文章中所讨论,当您需要对象副本时,请使用工厂方法。它具有以下优点:

  1. 如果需要,您还可以返回其他类的实例。例如,如果有人要复制LinkedList,则可以返回ArrayList
  2. 您可以选择需要进行深拷贝还是浅拷贝。
  3. 您可以决定哪些成员需要复制,哪些不需要。
  4. 不同的方法可以使用不同的名称来明确指出其职责。

我希望这篇文章能阐明在Java中创建对象副本时Java Cloneable接口(标记接口)的损坏行为和最佳实践。

学习愉快!

saigon has written 1440 articles

Leave a Reply