java - object.clone() 在 Java 中究竟是如何工作的?

标签 java oop object

我想了解 Object 类的 clone() 方法的工作原理。 Object 类中的注释说“此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。

以下是我对浅拷贝和深拷贝的理解..

Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure, not the elements. With a shallow copy, two collections now share the individual elements.

Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.

因此,如果我克隆一个对象并在克隆上修改它的任何可变元素,那么相同的内容应该反射(reflect)在创建克隆的第一个对象上,因为它们共享相同的内存。为了对此进行测试,我创建了 3 个类...

一个简单的 pojo..

package test.clone;

import java.util.Arrays;

public class Misc implements Cloneable{
    private String value;

    public Misc(String value) {
        super();
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Misc [value=" + value + "]";
    }


    protected Misc clone() throws CloneNotSupportedException{
        return (Misc)super.clone();
    }

}

需要克隆的类..

package test.clone;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class Victim implements Cloneable{
    private String name = "Renjith";
    private String[] educationList = {"EDU_1", "EDU_2", "EDU_3", "EDU_4"};
    private Misc[] miscList = {new Misc("1"), new Misc("2")};
    private List<Misc> miscList2 = new ArrayList<Misc>(Arrays.asList(miscList));

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String[] getEducationList() {
        return educationList;
    }
    public void setEducationList(String[] educationList) {
        this.educationList = educationList;
    }

    protected Victim clone() throws CloneNotSupportedException{
        return (Victim)super.clone();
    }
    public Misc[] getMiscList() {
        return miscList;
    }
    public void setMiscList(Misc[] miscList) {
        this.miscList = miscList;
    }


    public List<Misc> getMiscList2() {
        return miscList2;
    }
    public void setMiscList2(List<Misc> miscList2) {
        this.miscList2 = miscList2;
    }
    @Override
    public String toString() {
        return "Victim [name=" + name + ", educationList="
                + Arrays.toString(educationList) + ", miscList="
                + Arrays.toString(miscList) + ", miscList2=" + miscList2 + "]";
    }



}

进行克隆....和修改...的主类

public class Main {

    public static void main(String[] args) throws CloneNotSupportedException {
        Victim victim = new Victim();

        System.out.println(victim);

        Victim secondVictim = victim.clone();

        String[] educationList = {"EDU_1_mod", "EDU_2_mod", "EDU_3_mod", "EDU_4_mod"};
        Misc[] miscList = {new Misc("3"), new Misc("4")};
        List<Misc> miscList2 = new ArrayList<Misc>(Arrays.asList(miscList));

        secondVictim.setEducationList(educationList);
        secondVictim.setMiscList(miscList);
        secondVictim.setMiscList2(miscList2);

        System.out.println(secondVictim);

        System.out.println(victim);
    }

}

我期待的输出如下...

Victim [name=Renjith, educationList=[EDU_1, EDU_2, EDU_3, EDU_4], miscList=[Misc [value=1], Misc [value=2]], miscList2=[Misc [value=1], Misc [value=2]]] Victim [name=Renjith, educationList=[EDU_1_mod, EDU_2_mod, EDU_3_mod, EDU_4_mod], miscList=[Misc [value=3], Misc [value=4]], miscList2=[Misc [value=3], Misc [value=4]]] Victim [name=Renjith, educationList=[EDU_1, EDU_2, EDU_3, EDU_4], miscList=[Misc [value=3], Misc [value=4]], miscList2=[Misc [value=3], Misc [value=4]]]

但是我得到了...

Victim [name=Renjith, educationList=[EDU_1, EDU_2, EDU_3, EDU_4], miscList=[Misc [value=1], Misc [value=2]], miscList2=[Misc [value=1], Misc [value=2]]] Victim [name=Renjith, educationList=[EDU_1_mod, EDU_2_mod, EDU_3_mod, EDU_4_mod], miscList=[Misc [value=3], Misc [value=4]], miscList2=[Misc [value=3], Misc [value=4]]] Victim [name=Renjith, educationList=[EDU_1, EDU_2, EDU_3, EDU_4], miscList=[Misc [value=1], Misc [value=2]], miscList2=[Misc [value=1], Misc [value=2]]]

谁能告诉我这是怎么回事??

我已经经历了Understanding Object.clone() in Java , 但仍然无法理解....

最佳答案

您不是在修改列表/数组,而是用新的引用替换它们。尝试像这样更新您的 setter :

public void setMiscList(Misc[] miscList) {
    this.miscList[0] = miscList[0];
    this.miscList[1] = miscList[1];
}

public void setMiscList2(List<Misc> miscList2) {
    this.miscList2.set(0, miscList2.get(0));
    this.miscList2.set(1, miscList2.get(1));
}

这应该会修改共享对象,从而产生您预期的输出。

关于java - object.clone() 在 Java 中究竟是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41155969/

相关文章:

java - 如何仅将一个特定的已编译 .class 导入到 java 项目中

java - 通过 REST 传递 pdf 数据

Java 日志记录 API 开销

java - 关于如何获取测试 jar 来运行单独的测试 war 的指针(也许与 cargo ?)

excel - VBA 第一次创建类

javascript - 监控对象属性的变化

JavaScript - 对象 "this"

class - 是否可以使用接口(interface)部分的实现部分中声明的类

java - 如何设计我的 Java 类以使用已定义的 Utility 类的方法?

javascript - 添加到对象而不是覆盖它