【问题标题】:Cloneable behaviour可克隆行为
【发布时间】:2011-03-29 07:54:26
【问题描述】:

Java 文档说 -

类 Object 本身并不 实现接口Cloneable,所以 在对象上调用 clone 方法 其类是 Object 将导致 在运行时抛出异常。

为什么 Object 类中的 clone 方法是受保护的?是这样吗?

这意味着任何不实现可克隆的类在调用其克隆方法时都会抛出 CloneNotSupported 异常。

我运行了一个测试程序

public class Test extends ABC implements Cloneable{

    @Override
    public Object clone() throws CloneNotSupportedException {
        System.out.println("calling super.clone");
            return super.clone();
    }

    public static void main(String[] args) {
        Test t = new Test();
        try{
        t.clone();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class ABC{

}

从 Class Test 的克隆方法 super.clone 被调用?

为什么不抛出异常?

【问题讨论】:

  • [关闭]?这不是一个论坛。你应该只选择一个最好的答案并接受它。
  • [关闭] 在问题标题的末尾在 StackOverflow 上具有非常特殊的含义。这意味着至少有五个拥有关闭权限的用户或至少一个版主认为您的问题不符合 StackOverflow 上的预期标准。这目前不适用于您的问题,因此我将删除您问题标题前面的 [Closed] 标签。如果您确实希望 [Closed] 标记保留,请将其放回原处,我不会再次编辑它 - 或者要求我撤消更改,我会这样做。

标签: java superclass cloneable


【解决方案1】:

Test 实例t 的继承树看起来像

Object
  ABC
    Test

Test 也实现了Cloneable,这意味着当你调用super.clone() 方法时,Objectclone 方法将被调用。它检查实例t 是否实现Cloneable 接口。由于它确实实现了该方法,因此不会引发异常。

【讨论】:

    【解决方案2】:

    Cloneable 接口是一个标记接口,表示实现类支持克隆方法。 super.clone() 不抛出异常的原因是它被调用的基础对象是可通过继承克隆的。

    来自 Javadoc:

    一个类实现了 Cloneable 接口,以向 Object.clone() 方法指示该方法对该类的实例进行逐个字段的复制是合法的。

    在未实现 Cloneable 接口的实例上调用 Object 的 clone 方法会导致抛出异常 CloneNotSupportedException。

    见:Cloneable (Java Platform SE 6)

    【讨论】:

      【解决方案3】:

      因为你的类实现了Cloneable。来自CloneableJavadoc

      一个类实现了 Cloneable 接口,以向 Object.clone() 方法指示该方法对该类的实例进行逐个字段的复制是合法的。

      所以这允许使用Objectclone() 方法。它(再次根据 Javadoc)只是覆盖clone() 的约定。如果您不覆盖它并且Objectclone() 方法执行逐字段复制,如果其中一个字段本身不可克隆,您可能仍会得到CloneNotSupportedException。因此,最好覆盖它。

      【讨论】:

        【解决方案4】:

        为什么Object类protected中有clone方法?

        因此,选择支持克隆的类不会强制在其公共 API 中公开它。

        如您的示例所示,允许子类覆盖具有比方法继承版本更多访问权限的方法。您不能以这种方式减少方法的访问。

        这意味着任何不实现可克隆的类在调用其克隆方法时都会抛出 CloneNotSupported 异常。

        没错。

        从 Class Test 的克隆方法 super.clone 被调用?

        没错。

        为什么不抛出异常?

        因为你已经声明你的类实现了Cloneable。如果你没有这样做,它抛出一个异常......假设你的克隆方法仍然调用super.clone()

        【讨论】:

          【解决方案5】:

          这可能会给你答案为什么方法是受保护的 why is clone method protected

          它不会抛出异常,因为您实现了 Cloneable。来自可克隆文档:

          “一个类实现了 Cloneable 接口,以向 Object.clone() 方法指示该方法对该类的实例进行逐个字段的复制是合法的。 在未实现 Cloneable 接口的实例上调用 Object 的 clone 方法会导致抛出异常 CloneNotSupportedException。 "

          但是当你实现它时,你告诉 Object 实现,制作一个字段到字段的副本是合法的,所以它不会抛出异常。

          【讨论】:

            【解决方案6】:

            我会说一个很好的问题来迷惑受访者:)。

            至于它不抛出异常的原因。以对象的方式思考它。您的 t 对象属于实现可克隆的 Test 类。当您调用方法 super.clone 时,它​​仍然是类 Test 的对象,因此没有理由抛出 CloneNotSupported 异常。如果它是 Object 类本身的对象,它就会抛出异常。

            【讨论】:

              猜你喜欢
              • 2011-02-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-05-06
              • 1970-01-01
              • 2015-03-28
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多