首頁 > Java > java教程 > 主體

Java深拷貝,淺拷貝和Cloneable介面怎麼用

PHPz
發布: 2023-04-28 20:31:05
轉載
1242 人瀏覽過

1. Cloneable介面的介紹

Cloneable是標記型的介面(空介面),它們內部都沒有方法與屬性,實作Cloneable來表示該物件能被複製,能使用Object.clone()方法。如果沒有實作 Cloneable的類別物件呼叫clone()就會拋出CloneNotSupportedException異常。

Java深拷貝,淺拷貝和Cloneable介面怎麼用

可以理解為Cloneable介面發揮的是標記功能,自訂型別需要使用者自己標記出哪些類別是可以clone的,這個標記就是去實作Cloneable接口,實現了Cloneable介面後就表示該類別所建立的物件可以被克隆。

而要想使一個類別具備拷貝實例的功能,除了要實作Cloneable接口,還必須重寫Object類別的clone()方法。

Java深拷貝,淺拷貝和Cloneable介面怎麼用

可以看到Object類別的clone()方法是被protected修飾的,所以需要在重寫的clone()方法中透過super關鍵字去呼叫Object類中的clone()方法

Java深拷貝,淺拷貝和Cloneable介面怎麼用

2. 淺拷貝的介紹和實例

在拷貝一個物件時,對物件的基本資料類型的成員變量進行拷貝,但對引用類型的成員變數只進行引用的傳遞,並沒有創建一個新的對象,當對引用類型的內容修改會影響被拷貝的對象。簡而言之:淺拷貝僅僅複製所拷貝的對象,而不複製它所引用的對象。

觀察下面的程式碼,將Money類別的實例作為了Person類別的字段,new一個Person類別的物件person1,將這個person1物件拷貝到person2中,這裡的拷貝就是淺拷貝了,只是將person1物件的money引用拷貝到了person2,person1和person2中的momey指向的是同一個物件。

class Money {
    public double m = 666;
}
class Person implements Cloneable{
    int id;
    public Money money = new Money();

    public Person(int id) {
        this.id = id;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", money=" + money.m +
                '}';
    }
}
public class TestDemo3 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person(1);
        Person person2 = (Person) person1.clone();

        System.out.println("通过person2修改前的结果");
        System.out.println(person1);
        System.out.println(person2);

        person2.money.m = 888;
        person2.id = 2;
        System.out.println("通过person2修改后的结果");
        System.out.println(person1);
        System.out.println(person2);
    }
}
登入後複製

執行結果:

Java深拷貝,淺拷貝和Cloneable介面怎麼用

淺拷貝圖解:

Java深拷貝,淺拷貝和Cloneable介面怎麼用

3. 深拷貝的介紹和實例

在拷貝一個物件時,除了對基本資料類型的成員變數進行拷貝,對引用類型的成員變數進行拷貝時,建立一個新的物件來保存引用類型的成員變數。簡而言之:深拷貝把要複製的物件所引用的物件都複製了一遍。

下面的程式碼實現了深拷貝;實現person1物件的深拷貝,先用Person tmp引用來保存淺拷貝的結果,透過tmp引用找到money對象,再將money物件拷貝一份,然後賦值給tmp中的money,最後回傳tmp即可。這樣就將money所引用的物件也拷貝了一份,實現了深拷貝,此時person1和person2中的momey指向的是兩個不同的物件。

class Money implements Cloneable{
    public double m = 666;

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

}

class Person implements Cloneable{
    public int id;
    public Money money = new Money();

    public Person(int id) {
        this.id = id;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //return super.clone();
        Person tmp = (Person) super.clone();
        tmp.money = (Money) this.money.clone();
        return tmp;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", money=" + money.m +
                '}';
    }
}
public class Test2 {
    public static void main(String[] args) throws CloneNotSupportedException{
        Person person1 = new Person(1);
        Person person2 = (Person) person1.clone();

        System.out.println("通过person2修改前的结果");
        System.out.println(person1);
        System.out.println(person2);

        person2.money.m = 888;
        person2.id = 2;
        System.out.println("通过person2修改后的结果");
        System.out.println(person1);
        System.out.println(person2);
    }
}
登入後複製

執行結果:

Java深拷貝,淺拷貝和Cloneable介面怎麼用

深度拷貝圖解:

Java深拷貝,淺拷貝和Cloneable介面怎麼用

4.clone方法總結

java中clone方法是一個淺拷貝,引用類型依然在傳遞引用。我們可以透過繼續呼叫clone()方法,對 該物件的參考類型變數再實作一次clone()的方法來實現深拷貝。

以上是Java深拷貝,淺拷貝和Cloneable介面怎麼用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!