Cloneable在Java中如何工作,我如何使用它?
我想知道以下内容:
-
Cloneable
意味着我们可以通过实现接口来克隆或复制对象。这样做的优点和缺点是什么?Cloneable
- 如果对象是复合对象,递归克隆是如何发生的?
我想知道以下内容:
Cloneable
意味着我们可以通过实现接口来克隆或复制对象。这样做的优点和缺点是什么?Cloneable
你应该知道的第一件事是 - 不要使用它。Cloneable
用权利实施克隆是非常困难的,而且这种努力是不值得的。Cloneable
而不是使用其他一些选项,如apache-commons SerializationUtils
(deep-clone)或BeanUtils
(浅层克隆),或者只是使用复制构造函数。
有关 Josh Bloch 关于克隆的看法,请参阅此处,这解释了该方法的许多缺点。(Joshua Bloch是Sun的员工,领导了许多Java功能的开发。Cloneable
不幸的是,Cloneable本身只是一个标记接口,也就是说:它没有定义clone()方法。
这样做是更改受保护的 Object.clone() 方法的行为,该方法将为未实现 Cloneable 的类引发 CloneNotSupportedException,并为实现 Cloneable 的类执行成员级浅复制。
即使这是您要查找的行为,您仍然需要实现自己的 clone() 方法才能使其公开。
在实现你自己的 clone() 时,我们的想法是从 super.clone() 创建的对象开始,该对象保证属于正确的类,然后执行任何额外的字段填充,以防浅层副本不是你想要的。从 clone() 调用构造函数会有问题,因为如果子类想要添加自己的附加可克隆逻辑,这将中断继承;如果它要调用 super.clone(),在这种情况下,它将得到一个错误类的对象。
但是,此方法会绕过构造函数中可能定义的任何逻辑,这可能会带来问题。
另一个问题是,任何忘记覆盖 clone() 的子类都将自动继承默认的浅副本,这在可变状态的情况下可能不是您想要的(现在将在源和副本之间共享)。
由于这些原因,大多数开发人员不使用 Cloneable,而只是简单地实现复制构造函数。
有关Cloneable的更多信息和潜在陷阱,我强烈推荐Joshua Bloch的《Effective Java》一书。