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

object.clone()在java中究竟是如何工作的?,java,oop,object,Java,Oop,Object,我试图了解对象类的clone()方法的工作原理。 Object类中的注释表示“此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。” 以下是我对浅层和深层复制的理解 浅拷贝尽可能少地复制。一本浅薄的书 集合是集合结构的副本,而不是元素的副本。 使用浅拷贝,两个集合现在共享单个 元素 深度复制复制所有内容。收藏的深度副本是两个 包含原始集合中所有元素的集合 重复的 因此,如果我克隆了一个对象并在克隆上修改了它的任何可变元素,那么在创建克隆的第一个对象上应该会反映出这一点,因为两者共享相同的内存。为

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

以下是我对浅层和深层复制的理解

浅拷贝尽可能少地复制。一本浅薄的书 集合是集合结构的副本,而不是元素的副本。 使用浅拷贝,两个集合现在共享单个 元素

深度复制复制所有内容。收藏的深度副本是两个 包含原始集合中所有元素的集合 重复的

因此,如果我克隆了一个对象并在克隆上修改了它的任何可变元素,那么在创建克隆的第一个对象上应该会反映出这一点,因为两者共享相同的内存。为了测试这一点,我创建了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 + "]";
    }



}
package test.clone;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
公共类受害者实现可克隆{
私有字符串name=“Renjith”;
私有字符串[]educationList={“EDU_1”、“EDU_2”、“EDU_3”、“EDU_4”};
私人杂项[]杂项清单={新杂项(“1”),新杂项(“2”)};
私有列表miscList2=新的ArrayList(Arrays.asList(miscList));
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共字符串[]getEducationList(){
返回教育列表;
}
public void setEducationList(字符串[]educationList){
this.educationList=教育列表;
}
受保护的受害者克隆()引发CloneNotSupportedException{
返回(受害者)super.clone();
}
公共杂项[]获取杂项列表(){
返回列表;
}
公共无效集合杂项列表(杂项[]杂项列表){
this.miscList=miscList;
}
公共列表getMiscList2(){
返回错误列表2;
}
公共无效集合miscList2(列表miscList2){
this.miscList2=miscList2;
}
@凌驾
公共字符串toString(){
返回“受害者[name=“+name+”,教育列表=”
+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);
    }

}
公共类主{
公共静态void main(字符串[]args)引发CloneNotSupportedException{
受害者=新受害者();
系统输出打印LN(受害者);
受害者第二个受害者=受害者。克隆();
字符串[]educationList={“EDU_1_mod”、“EDU_2_mod”、“EDU_3_mod”、“EDU_4_mod”};
杂项[]杂项清单={新杂项(“3”),新杂项(“4”)};
List miscList2=新的ArrayList(Arrays.asList(miscList));
second.setEducationList(educationList);
second被害人.setMiscList(miscList);
第二个受害者。设置错误列表2(错误列表2);
System.out.println(第二受害者);
系统输出打印LN(受害者);
}
}
我希望得到如下输出

受害者[name=Renjith,educationList=[EDU_1,EDU_2,EDU_3,EDU_4], miscList=[Misc[value=1],Misc[value=2]],miscList2=[Misc[value=1], 杂项[value=2]]Victor[name=Renjith,educationList=[EDU_1_mod, EDU_2_mod、EDU_3_mod、EDU_4_mod],杂项列表=[Misc[value=3],杂项 [value=4]],miscList2=[Misc[value=3],Misc[value=4]] [name=Renjith,educationList=[EDU_1,EDU_2,EDU_3,EDU_4], miscList=[Misc[value=3],Misc[value=4],miscList2=[Misc[value=3], 杂项[值=4]]

但是我得到了

受害者[name=Renjith,educationList=[EDU_1,EDU_2,EDU_3,EDU_4], miscList=[Misc[value=1],Misc[value=2]],miscList2=[Misc[value=1], 杂项[value=2]]Victor[name=Renjith,educationList=[EDU_1_mod, EDU_2_mod、EDU_3_mod、EDU_4_mod],杂项列表=[Misc[value=3],杂项 [value=4]],miscList2=[Misc[value=3],Misc[value=4]] [name=Renjith,educationList=[EDU_1,EDU_2,EDU_3,EDU_4], miscList=[Misc[value=1],Misc[value=2],miscList2=[Misc[value=1], 杂项[值=2]]

谁能告诉我这有什么问题吗


我已经看过了,但仍然无法理解……

您不是在修改列表/数组,而是在用新的引用替换它们。尝试如下方式更新设置程序:

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));
}
public void setMiscList(Misc[]miscList){
this.miscList[0]=miscList[0];
this.miscList[1]=miscList[1];
}
公共无效集合miscList2(列表miscList2){
this.miscList2.set(0,miscList2.get(0));
this.miscList2.set(1,miscList2.get(1));
}
这将修改共享对象,从而产生预期的输出