淺拷貝本質上和深拷貝並無什麼區別,只是當被拷貝的對象內部包含着其餘的對象時,淺拷貝只是將那個所謂的其餘對象的引用拷貝出來到第二個對象中,那麼在內存中,這個所謂的其餘對象其實是同時被original對象和新拷貝的對象所引用;即它們共用同一內存區域。在Java中,Object.clone()實現的。默認狀況下,若是直接調用super.clone(),是淺拷貝的。java
The default version of clone() method creates the shallow copy of an object. The shallow copy of an object will have exact copy of all the fields of original object. If original object has any references to other objects as fields, then only references of those objects are copied into clone object, copy of those objects are not created. That means any changes made to those objects through clone object will be reflected in original object or vice-versa. Shallow copy is not 100% disjoint from original object. Shallow copy is not 100% independent of original object.ide
package org.copy; /** *淺拷貝 */ class Family implements Cloneable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Student implements Cloneable { private String name; private Family family; public String getName() { return name; } public void setName(String name) { this.name = name; } public Family getFamily() { return family; } public void setFamily(Family family) { this.family = family; } @Override protected Object clone() throws CloneNotSupportedException {/* * The class * Object does * not itself * implement the * interface * Cloneable, so * calling the * clone method * on an object * whose class * is Object * will result * in throwing * an exception * at run time */ return super.clone(); } } class StringObj implements Cloneable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } protected Object clone() throws CloneNotSupportedException { return super.clone(); } } public class CopyT { public static void main(String[] args) throws CloneNotSupportedException { Family family = new Family(); family.setName("Army-Family"); Student student1 = new Student(); student1.setFamily(family); student1.setName("James"); System.out.println(student1.getName() + " " + student1.getFamily().getName()); // OBJECT對象的clone()方法默認是淺拷貝,即只是拷貝了對象的引用,所以二者會同時改變 //A shallow copy just copies the values of the references in the class Student student2 = (Student) student1.clone(); System.out.println(student2.getName() + " " + student2.getFamily().getName()); /*System.out.println((student1.getName()==student2.getName())); System.out.println((student1.getFamily()==student2.getFamily()));*/ student2.setName("John"); student2.getFamily().setName("Agriculture-Family"); System.out.println(student1.getName() + " " + student1.getFamily().getName()); System.out.println(student2.getName() + " " + student2.getFamily().getName()); StringObj a = new StringObj(); a.setName("Hello"); StringObj b = (StringObj) a.clone(); System.out.println((a.getName()==b.getName())); System.out.println(a.getName()); System.out.println(b.getName()); b.setName("I like you"); System.out.println(a.getName()); System.out.println(b.getName()); /* * If a change is made to the value of a deeply copied reference, then * the copy does not reflect that change because it does not share the * same reference. */ } }
James Army-Familythis
James Agriculture-Familyspa
John Agriculture-Familycode
true對象
Hello索引
Hello內存
Helloget
I like youit
經過實驗結果,能夠看到,String類型的數據至關於被「深拷貝」了,original對象和new copied對象相對獨立,因此對後者的改變不會影響前者。在這一點上,淺拷貝和深拷貝是一致的,即它們都是相對獨立的兩個個體,即便它們存在拷貝與被拷貝的關係。
然而Family類型的數據則能夠明顯看到是被「深拷貝」了,original對象和new copied對象不獨立,對後者的改變促使前者也改變,這是由於二者共同使用同一塊索引。證實了Object.clone()的本質是進行淺拷貝。
深拷貝只是比淺拷貝更加完全,使得original對象和new copied對象徹底獨立。代碼實現上就須要咱們將clone()方法進行必定的修改。以前只是拷貝了內部對象的引用,如今則寫一個新的clone()方法,讓它作一件事,那就是從新開闢一段空間,再將拷貝的數據放到這個新的對象之中。複製的動做是同樣的,只是在此基礎上多了一個動做,那就是開闢新的存儲空間。所以只須要修改原始類(Student)的clone方法以下。
Deep copy of an object will have exact copy of all the fields of original object just like shallow copy. But in additional, if original object has any references to other objects as fields, then copy of those objects are also created by calling clone() method on them. That means clone object and original object will be 100% disjoint. They will be 100% independent of each other. Any changes made to clone object will not be reflected in original object or vice-versa.
protected Object clone() throws CloneNotSupportedException {/* * The class * Object does * not itself * implement the * interface * Cloneable, so * calling the * clone method * on an object * whose class * is Object * will result * in throwing * an exception * at run time */ Student student=(Student)super.clone(); student.family=(Family)family.clone(); return student; }
James Army-Family
James Army-Family
John Agriculture-Family
可見兩者是徹底獨立的,是真正意義上的拷貝。即所謂深拷貝。