Cloneable 接口是不是一个鸡肋?

Josh Bloch:如果你在我的书中读到关于克隆的文章,特别是当你在字里行间读到的时候,你就会知道我认为克隆已经被深深地破坏了。有一些设计缺陷,其中最大的一个是可克隆的接口没有克隆方法。这就意味着它根本就不起作用:制造一些可克隆的东西并不能说明你能用它做什么。相反,它说明了它在内部可以做些什么。它说,如果通过调用super。重复克隆结束调用对象的克隆方法,该方法将返回原始的字段副本。但它并没有说明你能用一个实现可克隆界面的对象做什么,这意味着你不能做多态克隆操作。如果我有一个Cloneable数组,你可能会认为我可以运行这个数组并克隆每个元素来生成一个数组的深层副本,但我不能。您不能强制调用克隆方法,因为Cloneable没有公共克隆方法,也没有对象。如果您试图转换成Cloneable并调用克隆方法,编译器会说您正在尝试调用对象上的受保护的克隆方法。事实的真相是,您没有通过实现Cloneable向客户提供任何功能,并且提供了一个公共克隆方法,而不是复制的能力。如果您提供一个具有不同名称的复制操作,并且没有实现Cloneable,那么这就没有比您得到的更好了。这基本上就是你使用复制构造函数所做的事情。复制构造函数方法有几个优点,我在书中对此进行了讨论。一个很大的好处是,可以让复制的副本与原来的版本有不同的表现。例如,您可以将LinkedList复制到ArrayList中。对象的克隆方法非常棘手。它是基于现场拷贝的,而且是“额外语言”。它在不调用构造函数的情况下创建对象。没有保证它保留构造函数所建立的不变量。多年来,无论是在阳光下还是在外面,都有很多臭虫,原因是如果你叫它“超级”。重复克隆直到你克隆了一个对象,你就有了一个对象的浅拷贝。克隆通常与被克隆的对象共享状态。如果这个状态是可变的,你就没有两个独立的对象。如果你修改了一个,其他的也会改变。突然,你会得到随机的行为。我现在用的东西很少了。我经常在具体的类上提供公共克隆方法,因为人们期望它。我没有抽象类实现Cloneable,也没有扩展它的接口,因为我不会将实现Cloneable的负担放置在扩展(或实现)抽象类(或接口)的所有类上。这是一个真正的负担,几乎没有什么好处。道格·李更进一步。他告诉我他不再使用克隆除了复制数组。您应该使用克隆来复制数组,因为这通常是最快的方法。但Doug的类型不再执行Cloneable了。他已经放弃了。我认为这并不是不合理的。很遗憾,Cloneable被打破了,但它确实发生了。最初的Java api在严格的期限内完成,以满足关闭的市场窗口。原来的Java团队做了一份令人难以置信的工作,但并不是所有的api都是完美的。Cloneable是一个弱点,我认为人们应该意识到它的局限性

来源:http://www.artima.com/intv/bloch13.html

原文地址:https://www.cnblogs.com/xiaohuBlog/p/7498504.html