欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java | 深拷贝与浅拷贝

程序员文章站 2022-05-28 14:33:16
...

Java中有三种类型的对象拷贝:
深拷贝(Deep Copy)、浅拷贝(Shallow Copy)、延迟拷贝(Lazy Copy)


深拷贝

深度拷贝将拷贝遇到的每个对象。副本和原始对象不会共享任何东西,所以它将是原件的副本。
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。
深拷贝相比于浅拷贝速度较慢并且花销较大。
Java | 深拷贝与浅拷贝
图示标注:深拷贝的情况下,在 SourceObject 中改变其中的引用对象 refObj ,不会影响 CopiedObject 的结果,反之亦然


浅拷贝

浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。
浅层复制将复制*属性,但是嵌套对象将在原始(源)对象和副本(目标)对象之间是共享
Java | 深拷贝与浅拷贝
图示标注:浅拷贝的情况下,在 SourceObject 中改变其中的引用对象 refObj ,会影响 CopiedObject 的结果


refObj

public class Subject {
 
   private String name; 

   public Subject(String s) { 
      name = s; 
   } 

   public String getName() { 
      return name; 
   } 

   public void setName(String s) { 
      name = s; 
   } 
}

SourceObj-浅拷贝/深拷贝

public class Student implements Cloneable { 
 
   // 对象引用 
   private Subject subj; 
 
   private String name; 
 
   public Student(String s, String sub) { 
      name = s; 
      subj = new Subject(sub); 
   } 
 
   public Subject getSubj() { 
      return subj; 
   } 
 
   public String getName() { 
      return name; 
   } 
 
   public void setName(String s) { 
      name = s; 
   } 
 
   public Object clone() { 
      //浅拷贝 
      try { 
         // 直接调用父类的clone()方法
         return super.clone(); 
      } catch (CloneNotSupportedException e) { 
         return null; 
      } 
      // 深拷贝,创建拷贝类的一个新对象,这样就和原始对象相互独立
      //Student s = new Student(name, subj.getName()); 
      //return s; 
   } 
}

测试文件

public class CopyTest {
    public static void main(String[] args) {
        // 原始对象
        Student stud = new Student("John", "Algebra");
        System.out.println("Original Object: " + stud.getName() + " - " + stud.getSubj().getName());

        // 拷贝对象
        Student clonedStud = (Student) stud.clone();
        System.out.println("Cloned Object: " + clonedStud.getName() + " - " + clonedStud.getSubj().getName());

        // 原始对象和拷贝对象是否一样:
        System.out.println("Is Original Object the same with Cloned Object: " + (stud == clonedStud));
        // 原始对象和拷贝对象的name属性是否一样
        System.out.println("Is Original Object's field name the same with Cloned Object: " + (stud.getName() == clonedStud.getName()));
        // 原始对象和拷贝对象的subj属性是否一样
        System.out.println("Is Original Object's field subj the same with Cloned Object: " + (stud.getSubj() == clonedStud.getSubj()));

        stud.setName("Dan");
        stud.getSubj().setName("Physics");

        System.out.println("Original Object after it is updated: " + stud.getName() + " - " + stud.getSubj().getName());
        System.out.println("Cloned Object after updating original object: " + clonedStud.getName() + " - " + clonedStud.getSubj().getName());
    }
}

参考

掘金:Java深拷贝和浅拷贝
*:Object_copying