【问题标题】:Java: why class designed for inheritance should contain protected clone method?Java:为什么为继承设计的类应该包含受保护的克隆方法?
【发布时间】:2017-11-13 22:41:43
【问题描述】:

我正在仔细阅读 Effective Java(作者 Joshua Bloch),我发现以下关于克隆的句子:

如果您为继承设计一个类,请注意,如果您选择不提供行为良好的受保护克隆方法,子类将无法实现 Cloneable。

我有点困惑,因为在我的小测试中:

public class Cloning {

    public static void main(String[] args) throws CloneNotSupportedException {

        Woman woman1 = new Woman("Marie Curie-Sklodowska", 33, "Physics");
        Woman woman2 = (Woman) woman1.clone();
    }

    static abstract class Person {
        protected String name;
        protected int age;

        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }

    static class Woman extends Person implements Cloneable {

        private String field;

        Woman(String name, int age, String field) {
            super(name, age);
            this.field = field;
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
}

我没有收到任何错误。我想,我没有正确理解这句话。有人可以解释一下作者的想法吗?

【问题讨论】:

  • 覆盖Person.clone() 并使其明确抛出CloneNotSupportedException。然后就不行了。
  • @AndyTurner 这听起来更像是选择提供一个行为不端的clone 方法。
  • @AndyTurner 这个问题似乎是重复的,但我根本没有得到答案。据我所知,clone() 可以很好地处理超类中的私有字段。
  • 嗯,我正在阅读关于同一主题的帖子,但我也不清楚接受的答案。它指出,制作私有字段“违背了承诺”,但我已经尝试过私有字段 - 它没有任何区别。克隆的对象是相同的。所以我的问题可能是克隆,但原来的不包含令人满意的答案。
  • 我重新提出这个问题,因为我不相信duplicate 得到了满意的回答。

标签: java cloning effective-java


【解决方案1】:

如果您为继承设计一个类,请注意,如果您选择不提供行为良好的受保护clone() 方法,子类将无法实现Cloneable

他错了。他们能。考虑:

public class A
{
    private int fieldA;
}

public class B extends A implements Cloneable
{
    public B clone() throws CloneNotSupportedException
    {
        return (B)super.clone();
    }
}

B.clone() 将返回调用它的B 实例的完美副本,包括A.fieldA。被反例驳斥:QED

[我知道这个clone() 不应该真的被声明为抛出CloneNotSupportedException,但它使演示更简单。]

这一切都很好奇,因为他刚才说了几句话:

一些程序员只是选择从不覆盖clone() 方法

为继承设计的类不应该实现它[Cloneable]

更奇怪的是,上面的第一句话是整个部分的最后一句话,并且完全没有论据或示例支持,除非整个部分旨在证明这一点,但事实并非如此。整个部分都如此混乱,以至于很难准确地弄清楚所声称的内容。克隆并不像他所说的那样难以理解或实施。也不重要。在 20 年的 Java 中,我没有在严肃的代码中使用过它,也没有在所谓的“复制构造函数”中使用它。

【讨论】:

  • 我原以为克隆部分的摘要有问题。但我认为它达到了它的目标——我很气馁使用clone() 方法和Cloneable 接口。感谢您的回答!
猜你喜欢
  • 2023-04-08
  • 2012-03-21
  • 2015-03-26
  • 2020-09-09
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 2018-08-23
相关资源
最近更新 更多