读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

 

posted on 2013-03-25 14:01  夜月升  阅读(151)  评论(0)    收藏  举报

导航