读Java编程艺术之笔记(浅复制/深复制)
浅复制(shallow copy),指在复制源对象中,如果某个成员数据是一个对象(除String和所有基本类型的包装类对象之外),clone()方法只是复制这个成员对象的引用,即,在复制后的对象中,它所具有的成员对象,只是对原来成员对象的引用,并没有真正复制这个成员对象。但对其他成员数据clone()则执行真正的复制,即分配内存,并将它们拷贝到这个内存中。所以浅复制的对象对其成员对象的任何修改,实际上是对源对象中成员对象的修改。
例如:
class SomeClass implements Cloneable{ OtherClass other; Integer myInt; int n; SomeClass(String title, int n){ other = new OtherClass(title); myInt = new Integer(100); this.n = n; } void setTitle(String title){ other.setName(title); } void setN(int n){ this.n = n; } void setInteger(int n){ myInt = n; } public String toString(){ return "other: "+other+" n: "+n+" myInt: "+myInt; } protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class OtherClass{ String name; OtherClass(String name){ this.name = name; } void setName(String name){ this.name = name; } public String toString(){ return name; } } public class CloneableTest { public static void main(String[] args) throws CloneNotSupportedException{ SomeClass sourceObj = new SomeClass("Java", 10); SomeClass targetObj = (SomeClass)sourceObj.clone(); System.out.println("content of sourceObj: "+sourceObj); System.out.println("content of targetObj: "+targetObj); targetObj.setTitle("JSP"); targetObj.setN(20); targetObj.setInteger(20); System.out.println("After modified(shallow copy)"); System.out.println("content of sourceObj: "+sourceObj); System.out.println("content of targetObj: "+targetObj); } }
其执行结果:
content of sourceObj: other: Java n: 10 myInt: 100 content of targetObj: other: Java n: 10 myInt: 100 After modified(shallow copy) content of sourceObj: other: JSP n: 10 myInt: 100 content of targetObj: other: JSP n: 20 myInt: 20
在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。继承自java.lang.Object类的clone()方法是浅复制。
那么如何执行深复制呢?提供两种改法:
/* 深复制 1 */
class SomeClass implements Cloneable{ OtherClass other; Integer myInt; int n; SomeClass(String title, int n){ other = new OtherClass(title); myInt = new Integer(100); this.n = n; } void setTitle(String title){ other.setName(title); } void setN(int n){ this.n = n; } void setInteger(int n){ myInt = n; } public String toString(){ return "other: "+other+" n: "+n+" myInt: "+myInt; } protected Object clone() throws CloneNotSupportedException{ SomeClass some = (SomeClass)super.clone();
//为其成员对象执行真正的复制 some.other = (OtherClass)other.clone(); return some; } } //此时需要成员对象的扩展Cloneable接口
class OtherClass implements Cloneable{ String name; OtherClass(String name){ this.name = name; } void setName(String name){ this.name = name; } public String toString(){ return name; } protected Object clone() throws CloneNotSupportedException{ return super.clone(); } } public class CloneableTest { public static void main(String[] args) throws CloneNotSupportedException{ SomeClass sourceObj = new SomeClass("Java", 10); SomeClass targetObj = (SomeClass)sourceObj.clone(); System.out.println("content of sourceObj: "+sourceObj); System.out.println("content of targetObj: "+targetObj); targetObj.setTitle("JSP"); targetObj.setN(20); targetObj.setInteger(20); System.out.println("After modified(deep copy)"); System.out.println("content of sourceObj: "+sourceObj); System.out.println("content of targetObj: "+targetObj); } }
/* 深复制 2 */
class SomeClass implements Cloneable{ OtherClass other; Integer myInt; int n; SomeClass(SomeClass someClass){ //此处执行所有成员数组的复制 other = new OtherClass(someClass.other.toString()); myInt = someClass.getInteger(); n = someClass.getN(); } SomeClass(String title, int n){ other = new OtherClass(title); myInt = new Integer(100); this.n = n; } void setTitle(String title){ other.setName(title); } void setN(int n){ this.n = n; } void setInteger(int n){ myInt = n; } Integer getInteger(){ return myInt; } int getN(){ return n; } public String toString(){ return "other: "+other+" n: "+n+" myInt: "+myInt; } protected Object clone() throws CloneNotSupportedException{ SomeClass some = new SomeClass(this); return some; } } class OtherClass { String name; OtherClass(String name){ this.name = name; } void setName(String name){ this.name = name; } public String toString(){ return name; } } public class CloneableTest { public static void main(String[] args) throws CloneNotSupportedException{ SomeClass sourceObj = new SomeClass("Java", 10); SomeClass targetObj = (SomeClass)sourceObj.clone(); System.out.println("content of sourceObj: "+sourceObj); System.out.println("content of targetObj: "+targetObj); targetObj.setTitle("JSP"); targetObj.setN(20); targetObj.setInteger(20); System.out.println("After modified(deep copy)"); System.out.println("content of sourceObj: "+sourceObj); System.out.println("content of targetObj: "+targetObj); } }
上述两段代码的执行结构都是:
content of sourceObj: other: Java n: 10 myInt: 100 content of targetObj: other: Java n: 10 myInt: 100 After modified(deep copy) content of sourceObj: other: Java n: 10 myInt: 100 content of targetObj: other: JSP n: 20 myInt: 20