clone()方法如何访问对象的字段? (JAVA)

时间:2013-06-30 21:33:09

标签: java reflection clone subclass native-code

我对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 aint bString cString d

我真正得到的是为什么这一切都是这样的。我的意思是:当我从B运行clone()时,它会调用来自A的clone(),然后调用对象的clone(),它返回一个对象。 test1的浅表副本。然后将这样的对象返回给A的clone(),然后将其返回给B的clone(),然后返回它。

现在,这种复制发生在哪里,复制的是什么? A和B clone()实际上没有做任何事情(或者技术上任何复制)。 B的方法只是调用A的方法,然后调用Object的方法。我昨天发现的first answer to this question强化了我对A和B的clone()方法的必要性的看法,指出在那个特殊情况下(恰好与我的相同),B clone()会甚至根本不需要。

足够公平,这意味着对象的clone()是进行所有复制的对象。现在点是:对象clone()如何看待所有必要字段?

我谦卑地假设这是因为Object是B的超类,但这种想法并没有真正起作用。实际上,A也是B的超类,但如果不是我放入B中的get / set方法,我就无法访问B的私有字段。而对象的clone()肯定不能用于我的获取/设置方法。

  • 我在这里缺少什么,或者我只是想了解一些相当于我头脑的东西?
  • Object中的clone()方法是某种“特殊”方法还是什么?
  • 从现在开始,我可以将它作为一个公理吗clone()制作一个对象的所有字段的浅层副本? (将它们作为私有或仅在子类/超类或其他任何内容中可见...)

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

1 个答案:

答案 0 :(得分:4)

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

  

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

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