【问题标题】:Confusion about cloneable interface and object.clone() in javajava中可克隆接口和object.clone()的混淆
【发布时间】:2009-07-01 05:17:37
【问题描述】:

如果我有:

class foo implements Cloneable

然后做:

bar = new foo();
bar.clone();

我得到一个浅拷贝,而无需像我通常在实现接口时那样编写任何bar.clone() 代码。

我的理解是接口的功能必须由实现它的类填充,Object.clone() 没有实现(根据文档,“类 Object 本身不实现接口 Cloneable”)

那么我的浅克隆从何而来?如果Object.clone() 没有实现,那么实现bar.clone() 的代码在哪里?我很困惑。

【问题讨论】:

    标签: java cloneable


    【解决方案1】:

    非常小心使用克隆。事实上,我会完全避免它。我从来没有需要它。但是...话虽如此,我读过的关于该主题的最佳讨论是 Joshua Bloch 在 Effective Java 中的。阅读第 11 条:“明智地覆盖克隆”。

    请帮自己一个忙并阅读该项目。我实际上建议阅读整章(以及本书的其余部分)。您需要了解的有关克隆的所有信息以及我为何提醒您注意它的原因都在其中。

    希望这会有所帮助。

    【讨论】:

    • +1 表示有效的 Java。关于克隆的讨论很棒,整本书也是如此。
    • 这几乎应该是唯一的答案。鉴于 Joshua Bloch 对 Cloneable 中固有的设计缺陷的出色讨论,几乎可以说这只是 Java 中的一个设计错误。使用复制构造函数/静态工厂几乎总是更好。
    【解决方案2】:

    Object.clone() 有一个实现:

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#clone()

    此链接解释了 Cloneable 接口: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Cloneable.html

    一个对象必须实现 Cloneable 接口才能调用 clone() 方法,否则,它会抛出一个 CloneNotSupportedException。

    根据定义,Java 中的所有类都扩展了 Object 基类,并且 Object 类有一个默认的 clone() 方法,尽管 Object 本身并没有实现 Cloneable。如果您不自己重写 Object 类的 clone() 方法,则会调用它。

    【讨论】:

    • 啊,我明白了。我误读了文档 - 对象确实有克隆()的代码,它只是没有实现可克隆那么那么强制可克隆实现以调用 class.clone()的机制是什么?这只是 JRE 意识到要故意检查的事情吗?
    • 快速回答——什么都没有。该接口决定了 Object 的 clone() 实现的行为。如果一个类是 Cloneable,Object.clone() 返回一个副本,否则抛出 CloneNotSupportedException。 Cloneable 接口本质上修改了其父类实现 clone() 的行为。
    【解决方案3】:

    如果我有:“类 foo 实现 可克隆”

    然后执行:bar = new foo(); bar.clone();

    我得到一个浅拷贝而不需要 像我一样编写任何 bar.clone() 代码 通常需要做的时候我 实现一个接口。

    只有在“foo”类中调用它时才有效,因为从Object 继承的 .clone() 方法是受保护的。

    我的理解是 接口的功能必须填写 通过实现它的类,并且 Object.clone() 没有实现 (根据文档,“类对象 本身并没有实现 接口可克隆")

    (1) Object.clone() 确实有一个实现。如果对象实现Cloneable,它会创建对象的浅拷贝。 (2) .clone() 方法不是任何接口的一部分。 (3) 拥有.clone() 方法和实现Cloneable 接口是完全不同的事情。如果你打算使用Objectclone方法,只需要实现Cloneable接口即可;但是,这是为您的类编写 clone 方法的推荐方法——从超类的 clone 方法获取其副本,该方法最终上升到 Objectclone 方法。

    【讨论】:

    • 谢谢,是的,你写的是我的错,因为我误读了这句话并将“可实现的实现”与“有一个实现”混为一谈
    • 为什么 "只有在类 "foo" 中调用它时才有效,因为从 Object 继承的 .clone() 方法是受保护的。" .what if我的子类调用 foo.clone()?绝对有可能对吗?
    • @amarnathharish:如果你的意思是foo 类没有实现任何clone() 方法,并且你有一个扩展foo 的类subfoo,并且在subfoo 内部调用@ 987654339@,不,那行不通,因为clone() 是在不同的包中声明的,而当受保护成员是在不同的包中声明
    • 我从来没有提到subfoo 在不同的包中,所以我想它可以从同一个包中访问而无需担心
    • @amarnathharish: 不,subfoo 可能与 foo 在同一个包中,但 Object.clone() 在不同的包中声明,因为 Object 在不同的包中
    【解决方案4】:

    我的理解是接口的功能必须由实现它的类填充,而 Object.clone() 没有实现(根据文档,“类 Object 本身不实现接口 Cloneable”)

    Object.clone() 没有实现是有区别的 并且 Object 类本身并不实现接口 Cloneable

    对象的克隆方法确实有实现,它对调用克隆方法的对象进行内存复制。

    你是对的,Object 类没有实现可克隆,它所做的只是检查对象是否可克隆。

    上面的答案点是你看书,我想我可以给出一个快速的解决方案 所以回答你的问题

    那么我的浅克隆从何而来? 对象的克隆方法

    如果 Object.clone() 没有实现,实现 bar.clone() 的代码在哪里? 它有实现,用本机代码编写。

    【讨论】:

      猜你喜欢
      • 2016-06-27
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 2011-10-07
      • 2012-07-13
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多