1

我对 Java 中的 clone() 方法有疑问。首先,我确实知道克隆方法被破坏了,但我们正在学校学习这个主题,我想牢牢掌握它(即使它可能不是最有效的做事方式) .

假设我处于这样的情况:

public class A implements Cloneable {
    private int a;
    private int b;

    // constructors, methods, etc.

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

public class B extends A {
    private String c;
    private String d;

    // constructors and all the rest

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

现在,如果在我的 main() 中,我有类似的东西:

B test1 = new B();
B test2 = (B) test1.clone();

我从经验中知道,该clone()方法会复制 test1 的所有值;事实上,由于适当的 get/set 方法,我可以访问和修改,int a和。int bString cString d

我真正不明白的是为什么这一切都是这样的。我的意思是:当我clone()从 B 运行时,它会调用clone()from A,而后者又会调用 Object's clone(),它返回一个对象,该对象是 test1 的浅表副本。然后将此类对象返回给 A clone(),后者将其返回给 B clone(),后者将其返回。

现在,这种复制发生在哪里以及复制了什么?A 和 Bclone()实际上并没有做任何事情(或技术上任何复制)。B 的方法只是调用 A 的方法,然后再调用 Object 的方法。我昨天发现的这个问题的第一个答案强化了我对 A 和 Bclone()方法的必要性的信念,指出在那种特殊情况下(恰好与我的相同),Bclone()甚至根本不需要。

很公平,这意味着 Object'sclone()是执行所有复制操作的那个。现在的重点是:Object 如何clone()查看所有必要的字段?

我谦虚地假设这是因为 Object 是 B 的超类,但这种想法并不真正站得住脚。事实上,A 也是 B 的超类,但如果不是因为我在 B 中放入的 get/set 方法,我将无法访问 B 的私有字段。而且clone()基于我的 get/set 方法,Object 肯定不起作用。

  • 这里有什么我遗漏的东西,还是我只是想理解一些让我头疼的东西?
  • Object中的clone()方法是某种“特殊”方法还是什么?
  • 从现在开始,我可以把它当作一个公理,即 Object 对 Object 的所有字段clone()进行浅拷贝吗?(它们是私有的或仅在子类/超类或其他任何东西中可见......)

(如果可以的话,请提供参考。不是我不信任你,只是我已经搜索了我所有的教科书和网上,我真的很想知道下次我有问题时在哪里看像这样! ;) )

4

1 回答 1

4

clone() 的 javadoc 解释了 Object.clone() 的作用:

类 Object 的方法 clone 执行特定的克隆操作。首先,如果该对象的类没有实现接口 Cloneable,则抛出 CloneNotSupportedException。请注意,所有数组都被认为实现了接口 Cloneable。否则,此方法会创建此对象的类的新实例,并使用此对象的相应字段的内容来初始化其所有字段,就像通过赋值一样;字段的内容本身不会被克隆。因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。

clone()方法是本机方法(只需查看源代码)。它是由 JVM 以本机代码实现的,它当然可以访问被克隆对象的所有状态。请注意,即使是使用反射的 Java 代码也可以访问任何对象的所有状态,甚至是私有状态。

于 2013-06-30T21:43:58.823 回答