浅拷贝本质上和深拷贝并无什么区别,只是当被拷贝的对象内部包含着其余的对象时,浅拷贝只是将那个所谓的其余对象的引用拷贝出来到第二个对象中,那么在内存中,这个所谓的其余对象其实是同时被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
可见两者是彻底独立的,是真正意义上的拷贝。即所谓深拷贝。