Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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中的克隆_Java_Clone_Cloneable - Fatal编程技术网

Java中的克隆

Java中的克隆,java,clone,cloneable,Java,Clone,Cloneable,我读到clone()方法实际上是一种浅层复制。 所以,我假设当P3中的一个字段的值改变时,P1中的字段也会改变。 但是,那没有发生。 我错过了什么 clone()方法实际上是一种浅层复制。 下面是您的示例中发生的情况: person1引用了名称。让我们将此引用称为A。将一个点引用到堆内存中的某个位置 将person1复制到person3后,person3中的名称引用(我们称之为引用B)指向堆内存中的相同位置但它不是相同的引用。它是指向堆内存中相同位置的两个不同引用 调用p3.setFirstNa

我读到clone()方法实际上是一种浅层复制。 所以,我假设当P3中的一个字段的值改变时,P1中的字段也会改变。 但是,那没有发生。 我错过了什么

clone()方法实际上是一种浅层复制。
下面是您的示例中发生的情况:

  • person1引用了名称。让我们将此引用称为A。将一个点引用到堆内存中的某个位置
  • 将person1复制到person3后,person3中的名称引用(我们称之为引用B)指向堆内存中的相同位置但它不是相同的引用。它是指向堆内存中相同位置的两个不同引用
  • 调用
    p3.setFirstName(“克隆的Sara”)
    时,引用B将更新为指向堆内存中的另一个位置。没有理由更改引用A指向的位置的值

  • 浅复制意味着它们有单独的字段,但这些字段引用相同的实例。这就像你把你朋友的电话号码复制到一部新手机上:你只有两个电话号码的副本,但他们呼叫的是同一部手机。这意味着,当您想要复制或克隆它时,您有一个字符串的新实例,具有复制的值。如果更改克隆的字符串,它不会影响原始字符串。@AndyTurner因此,在本例中,P3是P1的克隆。“他们不应该都引用同一个名字域吗?”Sara继续电话类比:你把电话号码复制到了另一部电话上。他们把同一件东西存放在两个地方;这两部手机没有把东西放在同一本电话簿里。如果你在一个地方更新它,它在另一个地方就不会更新。@KarelG不完全正确:克隆对象不会克隆字符串:它们都共享同一个实例,但如果在克隆后更新原始对象,它将只指向另一个字符串,而克隆将继续指向初始字符串值。哦,好的。我正在尝试克隆的例子。我应该如何修改Person类以真正反映浅层复制?i、 例如,P3中的更改反映在P1中,反之亦然?您可以将不可变的
    String
    类替换为可变类,如
    StringBuilder
    StringBuffer
    ,并让setter更改可变对象内的值,而不是使用操作符=将引用指向其他地方。
    class Person implements Cloneable {
    
        String firstName;
    
        public String getFirstName() {
            return firstName;
         }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public Person clone() throws CloneNotSupportedException {
                return (Person) super.clone();
            }
       }
    
        Person p1 = new Person();
        p1.setFirstName("P1 Sara");
    
        Person p3 = new Person();
        try {
            p3 = (Person) p1.clone();
        } catch (CloneNotSupportedException e) {
        }
    
        p3.setFirstName("cloned Sara");
        System.out.println("P3 : " + p3.getFirstName());
        System.out.println("P1: " + p1.getFirstName());