Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调用super.clone()方法时向下广播_Java_Downcast_Cloneable - Fatal编程技术网

Java 调用super.clone()方法时向下广播

Java 调用super.clone()方法时向下广播,java,downcast,cloneable,Java,Downcast,Cloneable,考虑以下程序 class A implements Cloneable { String str = null; public void set(String str) { this.str = str; } @Override public A clone() { A a = null; try { a = (A) super.clone();

考虑以下程序

class A implements Cloneable {
    String str = null;
    public void set(String str)
    {
        this.str = str;      
    }

    @Override
    public A clone()
    {
         A a = null;
         try {
              a = (A) super.clone();
              if(a.str!=null) {
                  System.out.println(a.str);
              }
              else {
                  System.out.println("null");
              }

         } 
         catch (CloneNotSupportedException e) {
               e.printStackTrace();
         }
         return a;    
    }
    public static void main (String args[])
    {
        A a = new A();
        a.set("1234");
        A b = a.clone();
    }
}
为什么上述程序的输出为1234且不为空

我希望为空,因为我的理解如下

  • 方法将创建父类类型的新对象(本例中为object),父类的属性将在该对象中被浅层复制

  • 当我们在clone()方法中进行向下转换时,子类中定义的属性将使用它们的默认值进行初始化,因为这是一个新对象

  • 但在查看输出后,似乎子类(this)的当前实例的属性值被复制到新构造的对象(在调用父类的克隆并向下转换之后)


    有人能告诉我们在向下广播时发生了什么吗?

    1234是正确的结果。。。让我们看看原因:

    创建一个新的
    a
    实例:

    A a = new A();
    
    将值设置为
    A.str

    a.set("1234");
    
    克隆a 首先,请注意,我们使用的是来自实例
    a
    clone()
    方法,所以我们来看看:

    @Override
    public A clone()
    {
         // create a NEW instance, it does not set a to null!!!
         // to reference the caller (a.clone in main) 
         // you must use this keyword i.e: this.str = null
         A a = null;
         try {
              // call Cloneable::clone() method 
              a = (A) super.clone();
    
              // now a is filled with data of this instance so print 1234
              if(a.str!=null) {
                  System.out.println(a.str);
              }
              // unused code in this case
              else {
                  System.out.println("null");
              }
    
         } 
         catch (CloneNotSupportedException e) {
               e.printStackTrace();
         }
         // return cloned instance
         return a;    
    }
    

    1234是正确的结果。。。让我们看看原因:

    创建一个新的
    a
    实例:

    A a = new A();
    
    将值设置为
    A.str

    a.set("1234");
    
    克隆a 首先,请注意,我们使用的是来自实例
    a
    clone()
    方法,所以我们来看看:

    @Override
    public A clone()
    {
         // create a NEW instance, it does not set a to null!!!
         // to reference the caller (a.clone in main) 
         // you must use this keyword i.e: this.str = null
         A a = null;
         try {
              // call Cloneable::clone() method 
              a = (A) super.clone();
    
              // now a is filled with data of this instance so print 1234
              if(a.str!=null) {
                  System.out.println(a.str);
              }
              // unused code in this case
              else {
                  System.out.println("null");
              }
    
         } 
         catch (CloneNotSupportedException e) {
               e.printStackTrace();
         }
         // return cloned instance
         return a;    
    }
    
    从文档中删除

    创建并返回此对象的副本。“复制”的确切含义可能取决于对象的类别。一般目的是,对于任何对象x,表达式:

    x、 克隆()!=x

    将为真,并且表达式:

    x、 克隆().getClass()==x.getClass()

    是的,但这些不是绝对的要求。而通常情况下:

    x、 克隆().equals(x)

    是的,这不是绝对的要求

    如您所见,典型的情况是
    X.equals(XClone)=true
    。 您不会遇到这种情况,因为
    A
    没有覆盖
    equals
    方法

    此外:

    类对象的克隆方法执行特定的克隆操作

    [……]

    此方法创建此对象类的新实例,并使用此对象对应字段的内容初始化其所有字段,就像通过赋值一样;字段的内容本身不是克隆的。因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作

    正如本文档所述,本机实现只创建您试图克隆的对象的
    浅拷贝。由于该行为,正确的输出是
    1234
    ,而不是
    null
    ,因为类中的
    字段
    刚刚分配给克隆实例。

    来自文档

    创建并返回此对象的副本。“复制”的确切含义可能取决于对象的类别。一般目的是,对于任何对象x,表达式:

    x、 克隆()!=x

    将为真,并且表达式:

    x、 克隆().getClass()==x.getClass()

    是的,但这些不是绝对的要求。而通常情况下:

    x、 克隆().equals(x)

    是的,这不是绝对的要求

    如您所见,典型的情况是
    X.equals(XClone)=true
    。 您不会遇到这种情况,因为
    A
    没有覆盖
    equals
    方法

    此外:

    类对象的克隆方法执行特定的克隆操作

    [……]

    此方法创建此对象类的新实例,并使用此对象对应字段的内容初始化其所有字段,就像通过赋值一样;字段的内容本身不是克隆的。因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作

    正如本文档所述,本机实现只创建您试图克隆的对象的
    浅拷贝。由于该行为,正确的输出是
    1234
    ,而不是
    null
    ,因为类中的
    字段仅分配给克隆实例

    方法将创建父类型(object)的新对象 在这种情况下)

    不,这就是你的错误所在
    Object.clone()
    将创建一个与调用它的对象的运行时类相同的运行时类的新实例,它是
    a
    ,而不是
    Object
    。它会将调用对象中
    A
    的所有字段浅拷贝到新对象中

    当我们在clone()方法中进行向下转换时,会定义属性 在子类中,将使用其默认值初始化,因为 这是一个新对象

    这没有任何意义,因为强制转换引用永远不会影响指向的对象的状态。如果引用指向的对象还不是
    A
    的实例,则强制转换将抛出
    ClassCastException
    。如果强制转换成功,则意味着引用指向的对象已经是
    A
    的实例,而您只是使用不同类型的引用指向同一对象。你将永远不会得到一个带有石膏的“新对象”

    方法将创建父类型(object)的新对象 在这种情况下)

    不,这就是你的错误所在
    Object.clone()
    将创建一个与调用它的对象的运行时类相同的运行时类的新实例,它是
    a
    ,而不是
    Object
    。它会将调用对象中
    A
    的所有字段浅拷贝到新对象中

    当我们在clone()方法中进行向下广播时,则