我正在学习 Java,因为我需要它作为我大学类(class)之一的先决条件。 我有 C++ 背景,所以理解 OOP 底层的逻辑并不是特别困难。 但这两种语言之间存在一些差异,其中一个我无法弄清楚的是 Java 中存在的对象克隆功能。 这个问题让我想起了 C++ 的复制构造函数,但含义不同。
在 Java 中,没有析构函数,内存由垃圾收集器管理,因此不存在 C++ 中遇到的堆内存问题。问题仅限于共享变量。
现在,通过阅读,我发现对象克隆(与复制构造函数不同)不是 OOP 语言应该提供的功能,因为它会创建跳过构造阶段的对象的另一个实例。此外,clone() 无法正确操作最终字段,并跳过初始化 block 。克隆背后的相同逻辑是“错误的”,因为“Cloneable”就像一个空接口(interface),仅用于在 Object.clone() 中进行类型检查,如果对象的类型不是 Cloneable,则引发异常。
所有克隆机制似乎都依赖于 Object.clone() 方法,该方法可以正确分配内存。支持clone() 的类层次结构中的每个子类型都应该调用“super.clone()”,直到调用Object 来分配所有必要的字段。 但是,如果实现 Cloneable 接口(interface)的子类型扩展了不这样做的父类(super class)型,会发生什么情况? 我正在向“Arnold、Gosling、Holmes”学习,对克隆的定义行为之一是:“允许子类支持克隆,但不公开支持它。这样的类不会实现 Cloneable,但如果默认克隆的实现不正确,该类提供了一个 protected 克隆实现,可以正确克隆其字段”。 这样,调用super.clone(),最终会碰到父类(super class)的 protected clone()方法,但该方法不能依赖于Object.clone(),因为父类(super class)本身并没有实现Cloneable。使用 new 运算符将是一个错误,因为将创建父类(super class)的实例,但缺少一些字段。
那么,在不可克隆的类中支持clone()(使用 protected 方法)真的有用吗? 如何解决具有不可克隆父类(super class)型的可克隆子类型的问题?
最佳答案
But what happens if a subtype, implementing the
Cloneable
interface, extends a supertype not doing so?
如果它只是实现 Cloneable
而没有实际重写 clone()
(是的,这也是可能的!),那么不会造成任何损害。
如果它重写 clone()
并返回一个不是从 super.clone()
检索到的实例,那么它就破坏了它的所有子类。这是 clone()
公认的陷阱之一(《Effective Java》中已介绍)。
how can one solve the problem of a Cloneable subtype with non-Cloneable supertype?
如上所述,只要不可克隆的父类(super class)型不重写 clone()
(是的,这是另一种可能性!)或者确实覆盖它,但以兼容的方式。
关于java - Java 中对象克隆的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32631434/