JAVA中clone()相關知識點

1.java語言中Arraylist=賦值與clone()得到的結果的不同在於:

    =就相當於引用,如果對其進行增刪,那麼操作的是用一個對象,二者會相互影響。
    而clone相當於copy一份,兩者相互獨立,可以單獨進行操作,二者互不影響。
2.java種所有的類都是Object的子類。在Object類中有一個clone方法定義如下:

protected native Object clone() throws CloneNotSupportedException;

該方法的修飾符爲protected,即表明該方法僅可以在子類中調用。

但需要注意的是需要先對其進行override而後實現Cloneable接口,否則會出現CloneNotSupportedExeception異常。

3.Cloneable接口僅僅是個標誌,它裏面是空的。Object的clone方法是本地方法,比較有效率

使用clone方法的幾個條件。

1)在派生類中實現Cloneable接口。

2)爲了獲取對象的一份拷貝,我們可以利用Object類的clone方法。

3)在派生類中覆蓋積累的clone方法,聲明爲public。

4)在派生類的clone方法中,調用super.clone()。

4.典型重寫與調用代碼:

public class Test implements Cloneable{
    private int f1;

    public Test(int f1) {
        this.f1 = f1;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public int getf1() {
        return f1;
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Test test = new Test(1);
        Test cloned = (Test) test.clone();
        System.out.println(cloned.getf1());
    }
}

5.深拷貝與淺拷貝:

如上4所說爲淺拷貝,使用系統自帶的toString()函數可以調得其名稱和具體的地址

例:

com.yaolong.clone.Person@28084850 

com.yaolong.clone.Person@37c390b8 

可以看出,通過類似以上的淺拷貝,前後兩者的對象地址是不一樣的。

但是,通過輸出getName().hashCode()可以得出兩者依然指向同一個hashcode對應的相同對象,這就是典型的淺拷貝。

pName:115864556 

p1Name:115864556 


而實現深拷貝需要使用類似如下的代碼:


    public Head head;
    public Body() {}
    public Body(Head head) {this.head = head;}


    @Override
    protected Object clone() throws CloneNotSupportedException {
        Body newBody =  (Body) super.clone();//深克隆
        newBody.head = (Head) head.clone();//深克隆
        return newBody;
    }


}
static class Head implements Cloneable{
    public  Face face;


    public Head() {}
    public Head(Face face){this.face = face;}
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();//淺克隆
    }

public static void main(String[] args) throws CloneNotSupportedException {


    Body body = new Body(new Head());


    Body body1 = (Body) body.clone();


    System.out.println("body == body1 : " + (body == body1) );


    System.out.println("body.head == body1.head : " +  (body.head == body1.head));

同時,需要明白的是,這也不是嚴格意義上的深複製,因爲其引用的對象還應用了其他的對象,這些其他對象的地址並沒有被完全拷貝,因此在一定意義上來說還是進行淺複製,不過相比上面的直接super.clone()來講已經是深複製了。由此可見,實現徹底的深拷貝(深複製)設計非常麻煩的。

深淺拷貝參考blog,講的很詳細~:http://blog.csdn.net/u014727260/article/details/55003402


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章