为什么需要覆盖Object的克隆方法

时间:2013-07-02 11:40:02

标签: java clone override

java中的每个类都隐式扩展Object class.clone()在Object中受到保护。 对于知道的子类,protected方法是可见的。那么为什么我们需要覆盖? 即使我阅读了很多网站,我也无法理解这些概念。 请说清楚。 感谢。

3 个答案:

答案 0 :(得分:2)

这是因为克隆只能从子类中看到。其他类,甚至来自同一个包的类,都不会在子代中看到克隆,因此无法克隆该子代:

class Test2 implements Cloneable {
}

public class Test1 {


    public static void main(String[] args) throws Exception {
        Test2 t2 = new Test2();
        t2.clone(); <-- compile time error: Method clone() from type Object is not visible
    }
}

答案 1 :(得分:1)

您只需要覆盖需要自己实现的超类方法。如果您想要超类的默认行为,则无需覆盖

答案 2 :(得分:1)

让我们一步一步地了解克隆

  • 虽然每个对象都继承Object.clone(),但默认情况下克隆 ON。这意味着如果您尝试clone()某个随机对象,您可能会得到 CloneNotSupportedException

  • 启用克隆,对象的类或其中一个超类必须实现 Cloneable 接口。它只是一个标记接口,没有它,就会抛出上面提到的异常。

  • 假设已启用克隆,则默认实施将继承为 protected 。因此,该类仍然可以使用它来创建其对象的副本,但它尚未被公众调用。

  • 现在,如果您的班级想要提供从课堂外部制作其对象的副本,那么它可以覆盖 Object.clone() public ,只需在里面调用super.clone()即可使用默认实现。

  • 这让我想到了最后一点。 默认实现是创建对象的浅层副本,这意味着它只需将所有基元和引用值复制到新对象上。这意味着,复杂的数据结构,如Map将被共享,因为两个副本虽然有两个不同的引用,但它们将指向相同的Map

    这就是为什么覆盖大多数时候必须提供自己的实现(更好地称为)对象的深层拷贝,以便克隆是不与源对象共享任何状态,可以独立修改而不影响其他状态。