理解Java中的Object.clone()

时间:2013-05-22 09:40:09

标签: java

我知道使用这种克隆机制并不是一个好主意(因为它像一些作者所说的那样“破坏”),尽管我需要帮助理解它是如何工作的。我们给出了以下类层次结构:

class N implements Cloneable{
    protected int num;
    public N clone() throws CloneNotSupportedException{
        return (N)super.clone();
    }
}

class M extends N{
    protected String str;
    public M clone() throws CloneNotSupportedException{
        M obj = (M)super.clone();
        obj.setString(new String(this.str));
        return obj;
    }
    void setString(String str){
        this.str = str;
    }
}

N扩展Object以来,super.clone()如何返回N的实例? super.clone()实际上是Object.clone(),它返回对类Object的对象的引用。那么我们为什么能够将它投射到NN的成员num不属于班级Object。默认行为如何实际设法自动克隆此变量(因为它在类Object中没有它的记录)?

此外,对于M. M.clone()我们正在将类N(由super.clone()返回)中的对象转换为类M的对象。我知道所有这些都是有效的,但我不明白为什么。

4 个答案:

答案 0 :(得分:6)

Object#clone是一个本机方法,它创建对象的低级二进制副本,从而生成同一个类的另一个实例。因此,向下倾斜是安全的。

请注意,这是唯一的方式,可以使用多态克隆方法。

答案 1 :(得分:2)

从技术上讲,Object.clone()是一种原生方法:

protected native Object clone() throws CloneNotSupportedException;

JVM在内部知道当前对象的大小,以及对象的类型。因此,它可以创建适当的对象作为按位复制并返回对它的引用。

答案 2 :(得分:0)

  1. 由于N扩展了Object,super.clone()如何返回 N?
  2. 的实例
  3. super.clone()实际上是Object.clone(),它返回一个引用 到Object类的对象。那我们为什么能把它投到N?
  4. N的成员num不在Object类中。怎么样 默认行为实际上设法自动克隆此 变量(因为它在Object类中没有它的记录)?
  5. 答案:

    1. 在运行时,您在N类的实例中调用其父克隆方法。考虑它就像你在你的N级中覆盖它一样完全相同。 Object类是本机和抽象对象。实际上,当你调用N.toString()时,你会调用JVM在N层次结构中找到的第一个toString方法。
    2. 同样在这里,记住你是N级的一个实例。
    3. 它没有:How do I copy an object in Java?

答案 3 :(得分:0)

您还可以使用 XStream 对象来克隆您的对象,如下所示:

public static <T> T cloneObject(
    T object) {
    XStream xstream = new XStream();
    return (T) xstream.fromXML(xstream.toXML(object));
  }