【问题标题】:Java: Rationale of the Cloneable interfaceJava:Cloneable 接口的基本原理
【发布时间】:2010-10-17 02:24:06
【问题描述】:

为什么java.lang.Cloneable接口中没有指定.clone()方法?

【问题讨论】:

    标签: java clone specifications cloneable


    【解决方案1】:

    基本上,这是一个损坏的界面。 Ken Arnold 和 Bill Venners 在Java Design Issues 中讨论了它。

    阿诺德:

    如果我在这一点上是上帝,很多人可能很高兴我不是,我会说弃用 Cloneable 并有一个 Copyable,因为 Cloneable 有问题。除了拼写错误之外,Cloneable 不包含clone 方法。这意味着您无法测试某个东西是否是Cloneable 的实例,将其转换为Cloneable,然后调用clone。您必须再次使用反射,这很糟糕。这只是一个问题,但我肯定会解决一个问题。

    【讨论】:

    • 为什么它没有在 Java 8 中修复?之前没有删除/更改过 Java 的损坏/无效部分吗?
    • 因为几个人这么说就“破”了? “可克隆不包含克隆方法”是的,它的文档从未说过它会。 “这意味着你不能测试某个东西是否是 Cloneable 的实例,将其转换为 Cloneable,然后调用 clone。”同样,这根本不是Cloneable 的目的。 Cloneable 只是为了让Object.clone() 抛出异常。它从来都不是您调用clone 的接口。如果 Java 有这样的接口可能会很好,但缺少一个不会使另一个接口 (Cloneable) 损坏。
    • @newacct 仅仅因为它的行为与其文档相匹配并不能使它成为一个好的界面。我猜如果您的代码不起作用,您只需更改文档?
    【解决方案2】:

    在 Java 错误数据库中查看此错误:

    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4098033

    本质上,这是 Java 早期版本中的一个设计缺陷,他们不打算在 Cloneable 接口中修复,因为这样做会破坏与某些现有代码的兼容性。

    【讨论】:

    • @EpicPandaForce 可能是因为我们不想在某些情况下模仿 C++。克隆应该小心使用,大多数时候它并没有达到你想要的效果。 Java 中缺少的是 const 参数,但是复制每个(可变)对象实例并不是一个好的解决方案。是的,Java 在某些方面很糟糕,这就是其中之一。使用 Kotlin / 数据类。
    【解决方案3】:

    在 Java 中,存在标记接口的概念。 Cloneable 接口没有方法或字段,仅用于识别可克隆的语义。

    来自dev-x 网站:

    您经常会在 Java 中遇到没有行为的接口。换句话说,它们只是空的接口定义。这些被称为标记接口。 Java API 中的一些标记接口示例包括:

    【讨论】:

    • 我不认为这是一个奇怪的概念。有时能够查看某些东西是否可以充当替代类型很有用。正如其他人所说,Cloneable 已经坏了。
    • 它们应该充当混入。不是我最喜欢的强类型语言(如 java)中的机制,但它对 Serializable 是有意义的。
    • @Serializable 会更有意义。或者至少如果注释早在十年前就可以做到。
    • 我喜欢 tom 的最后一条评论 :) 有不少功能在十年前就应该有……
    【解决方案4】:

    在我从事的项目中,我们创建了一个名为 PublicCloneable 的接口, 它包含克隆方法并指定它是公共的。

    我觉得这个很有用:有一个 clone 方法,但你无法访问它并没有多大帮助。

    public interface PublicCloneable extends Cloneable {
        public Object clone();
    }
    

    【讨论】:

    • 如何使用这个接口(PublicConeable)?
    • @Otto:例如,CloneHelper 的方法是 public static PublicCloneable copy(PublicCloneable obj),它检查 null 或只是 copy(Object obj),并检查 null 和 instanceof PublicCloneable跨度>
    • 当你从本地缓存返回一个对象时......也就是说,序列化/反序列化可能更安全。
    • "并指定它是公开的。" - 实际上,接口中定义的方法默认是公共的。无需在代码中提及这一点。 @NicolasC
    【解决方案5】:

    因为克隆方法是在 Object 类中实现的,因为它的“特殊”条件:任何类型对象的内存副本。

    【讨论】:

      猜你喜欢
      • 2015-04-25
      • 1970-01-01
      • 2014-05-13
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      • 2011-03-11
      • 1970-01-01
      相关资源
      最近更新 更多