java - Java 中对象克隆的行为

标签 java

我正在学习 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/

相关文章:

java - 注解默认值 "null"

java - 调整 JScrollPane 和 JTabbedPane 大小的问题

Java Animation,以1x,1y的频率更新动画

java - 构建项目时的 Maven 配置

java - 获取在 2D 平面上相互接触的对象的数量副本(Java 算法)

java - GWT警告: "Call to Enum method toString when enum obfuscation is enabled"

javascript - 在 Javascript 中将 Java 颜色转换为 RGB

java - Cobertura 和 jetty

java - 未在 distributionManagement 元素内的 POM 或 -DaltDep loymentRepository=id::layout::url 参数中指定存储库元素

java - 调用wait()时发生IllegalMonitorStateException