【问题标题】:Understanding Object.clone() in Java理解 Java 中的 Object.clone()
【发布时间】:2013-05-17 07:27:46
【问题描述】:

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

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 中。默认行为实际上是如何设法自动克隆这个变量的(因为它在 Object 类中没有它的记录)?

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

【问题讨论】:

标签: java


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    protected native Object clone() throws CloneNotSupportedException;
    

    而且JVM内部知道当前对象有多大,对象的类型是什么。因此,它可以将适当的对象创建为按位复制并返回对它的引用。

    【讨论】:

      【解决方案3】:
      1. 既然 N 扩展了 Object,那么 super.clone() 如何返回一个 N 的实例?
      2. super.clone() 实际上是 Object.clone() 返回一个引用 到 Object 类的对象。为什么我们能够将其转换为 N?
      3. N 有一个不在 Object 类中的成员 num。如何
        默认行为实际上设法自动克隆它 变量(因为它在 Object 类中没有记录)?

      答案:

      1. 在运行时,您在 N 类的实例中调用其父克隆方法。将其视为与您在 N 类中覆盖它完全相同的事情。 Object 类是一个原生的抽象对象。实际上,当您调用 N.toString() 时,您调用的是 JVM 在 N 的层次结构中找到的第一个 toString 方法。
      2. 这里也一样,记住你在 N 类的一个实例中。
      3. 它没有:How do I copy an object in Java?

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 2015-01-29
          • 1970-01-01
          • 1970-01-01
          • 2012-04-01
          • 2017-10-09
          • 2013-01-06
          • 1970-01-01
          • 2013-07-19
          • 1970-01-01
          相关资源
          最近更新 更多