深度复制和浅复制的区别是什么?


当前回答

浅拷贝:将成员值从一个对象复制到另一个对象。

深度复制:将成员值从一个对象复制到另一个对象。                       任何指针对象复制和复制。

例子:

class String
{
     int   size;
     char* data;
};

String  s1("Ace");   // s1.size = 3 s1.data=0x0000F000

String  s2 = shallowCopy(s1);
 // s2.size =3 s2.data = 0X0000F000
String  s3 = deepCopy(s1);
 // s3.size =3 s3.data = 0x0000F00F
 //                      (With Ace copied to this location.)

其他回答

为了补充其他答案,

对象的浅拷贝对值类型执行逐值复制 基于属性,并通过引用复制基于引用类型的属性。 对象的深度复制对基于值类型的对象执行逐值复制 属性,以及基于引用类型的按值复制 层次结构深处的属性(引用类型)

浅复制-原始和浅复制对象中的引用变量引用公共对象。

深度复制-原始和深度复制对象中的引用变量引用不同的对象。

克隆总是做浅拷贝。

public class Language implements Cloneable{
    
    String name;
    public Language(String name){
        this.name=name;
    }
    
    public String getName() {
        return name;
    }
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

主类如下-

public static void main(String args[]) throws ClassNotFoundException, CloneNotSupportedException{

      ArrayList<Language> list=new ArrayList<Language>();
      list.add(new Language("C"));
      list.add(new Language("JAVA"));

      ArrayList<Language> shallow=(ArrayList<Language>) list.clone();
      //We used here clone since this always shallow copied.

      System.out.println(list==shallow);
      
      for(int i=0;i<list.size();i++)
      System.out.println(list.get(i)==shallow.get(i));//true
      
      ArrayList<Language> deep=new ArrayList<Language>();
      for(Language language:list){
          deep.add((Language) language.clone());
      }
      System.out.println(list==deep);
      for(int i=0;i<list.size();i++)
          System.out.println(list.get(i)==deep.get(i));//false
      
} 

以上输出为-

假真假真 假假假

原始物体的任何变化都将反映在浅物体上,而不是在深物体上。

  list.get(0).name="ViSuaLBaSiC";
  System.out.println(shallow.get(0).getName()+"  "+deep.get(0).getName());

输出- ViSuaLBaSiC C

浅拷贝:将成员值从一个对象复制到另一个对象。

深度复制:将成员值从一个对象复制到另一个对象。                       任何指针对象复制和复制。

例子:

class String
{
     int   size;
     char* data;
};

String  s1("Ace");   // s1.size = 3 s1.data=0x0000F000

String  s2 = shallowCopy(s1);
 // s2.size =3 s2.data = 0X0000F000
String  s3 = deepCopy(s1);
 // s3.size =3 s3.data = 0x0000F00F
 //                      (With Ace copied to this location.)

广度vs深度;从引用树的角度考虑,将对象作为根节点。

浅:

变量A和B指的是不同的内存区域,当B被分配给A时,这两个变量指的是相同的内存区域。后来对其中一个内容的修改立即反映在另一个的内容中,因为它们共享内容。

深:

变量A和B指的是不同的内存区域,当B被分配给A时,A所指向的内存区域中的值被复制到B所指向的内存区域。后来对其中一项内容的修改仍为A或B所独有;内容不共享。

复制array:

Array是一个类,这意味着它是引用类型,因此array1 = array2的结果 在引用同一个数组的两个变量中。

但是看看这个例子:

  static void Main()
    {
        int[] arr1 = new int[] { 1, 2, 3, 4, 5 }; 
        int[] arr2 = new int[] { 6, 7, 8, 9, 0 };

        Console.WriteLine(arr1[2] + " " + arr2[2]);
        arr2 = arr1;
        Console.WriteLine(arr1[2] + " " + arr2[2]); 
        arr2 = (int[])arr1.Clone();
        arr1[2] = 12;
        Console.WriteLine(arr1[2] + " " + arr2[2]);
    }

浅克隆意味着只复制克隆数组所表示的内存。

如果数组包含值类型对象,则复制值;

如果数组包含引用类型,则只复制引用-因此有两个数组,其成员引用相同的对象。

要创建复制引用类型的深度复制,必须循环遍历数组并手动克隆每个元素。