在Java中理解Object.clone()方法

3

我知道使用这种克隆机制并不是一个好主意(因为一些作者认为它是“有缺陷的”),尽管如此,我需要帮助理解它是怎么工作的。我们有以下类层次结构:

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类对象的引用。我们为什么能将其强制转换为N类?N有一个成员变量num,但在Object类中没有记录它,那么默认行为是如何自动克隆这个变量的呢?
同样的问题也出现在M类中。在M.clone()中,我们将从super.clone()返回的N类对象转换为M类对象。我知道这些都是有效的,但我不明白为什么。

可能是Java: clone()操作调用super.clone()的重复问题。 - user207421
4个回答

6

Object#clone是一种本地方法,它可以制作一个低级二进制副本,从而产生另一个与原实例相同类的实例。因此,向下转型是安全的。

请注意,这是拥有多态克隆方法的唯一途径


2

在技术上,Object.clone() 是一个本地方法:

protected native Object clone() throws CloneNotSupportedException;

JVM内部知道当前对象的大小和类型。因此,它可以创建适当的对象作为位拷贝并返回其引用。


0

你也可以使用XStream对象来克隆你的对象,像这样:

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

0
  1. 由于N扩展了Object类,那么super.clone()如何返回N类的实例?
  2. super.clone()实际上是Object.clone(),它返回一个指向Object类对象的引用。为什么我们能将其强制转换为N类?
  3. N有一个成员变量num,而Object类中没有这个变量。默认行为如何自动克隆这个变量(因为在Object类中没有记录它)?

答案:

  1. 在运行时,您位于N类的实例内部,调用其父类的clone方法。将其视为如果您在N类中覆盖了它完全相同的事情。Object类是本地和抽象对象。当您调用N.toString()时,实际上调用了JVM在N层次结构中找到的第一个toString方法。
  2. 同样,在这里记住您在N类的实例中。
  3. 不会:如何在Java中复制对象?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接