Clone()方法詳解


一、克隆的原理與應用

clone在堆上分配內存,分配的內存和源對象(即調用clone方法的對象)相同,然后再使用原對象中對應的各個域,填充新對象的域, 填充完成之后,clone方法返回,一個新的相同的對象被創建,同樣可以把這個新對象的引用發布到外部。如果,想要對該對象進行處理,又想保留原來數據進行接下來的操作,clone就很方便。

二、克隆的實現

1、被克隆的類必須自己實現Cloneable 接口,以指示 Object.clone() 方法可以合法地對該類實例進行按字段復制。Cloneable 接口實際上是個標識接口,沒有任何接口方法。

2、覆蓋Object.clone()方法。

三、淺拷貝與深拷貝

淺拷貝:在填充新對象域的時候,進行簡單的字段賦值。

深拷貝:按照慣例,此方法返回的對象應該獨立於該對象(正被復制的對象)。要獲得此獨立性,在 super.clone 返回對象之前,有必要對該對象的一個或多個字段進行修改。這通常意味着要復制包含正在被復制對象的內部“深層結構”的所有可變對象,並使用對副本的引用替換對這些對象的引用。如果一個類只包含基本字段或對不變對象的引用,那么通常不需要修改 super.clone 返回的對象中的字段。(簡單來說,就是將該對象內部的對象也克隆一份,而不是簡單的引用賦值)

可變對象:對象創建后字段值可以改變)

淺拷貝:

class Head {
    String s;
    void set(String s1) {
        s = s1;
    }
}
public class Person implements Cloneable{
    
    Head head;
    Person(Head head) {
        this.head = head;
    }
    protected Object clone() throws CloneNotSupportedException{
        return super.clone();
    }
    public static void main(String[] args) throws CloneNotSupportedException{
        Person p = new Person(new Head());
        Person p1 = (Person)p.clone();
        System.out.println("p == p1 " + (p == p1));
        System.out.println("p.head == p1.head " + (p.head == p1.head));
    }

}

 輸出結果:

p == p1 false
p.head == p1.head true

結果分析:

可以從結果過中看到,克隆創建了一個新的Person對象,但是p.head與p1.head仍然指向同一對象,也就是說p與p1仍然存在聯系,這是我們不想看到的。

 

深拷貝:

class Head implements Cloneable{
    String s;
    void set(String s1) {
        s = s1;
    }
    protected Object clone() throws CloneNotSupportedException{
        return super.clone();
    }
}
public class Person implements Cloneable{
    
    Head head;
    Person(Head head) {
        this.head = head;
    }
    protected Object clone() throws CloneNotSupportedException{
        Person p = (Person)super.clone();
        p.head = (Head)head.clone();
        return p;
    }
    public static void main(String[] args) throws CloneNotSupportedException{
        Person p = new Person(new Head());
        Person p1 = (Person)p.clone();
        System.out.println("p == p1 " + (p == p1));
        System.out.println("p.head == p1.head " + (p.head == p1.head));
    }

}

 輸出結果:

p == p1 false
p.head == p1.head false

結果分析:要實現深層拷貝要將對象內部的對象拷貝。

好文推薦:詳解Java中的clone方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM