溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java深拷貝,淺拷貝和Cloneable接口怎么用

發(fā)布時(shí)間:2022-08-24 11:09:09 來源:億速云 閱讀:143 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Java深拷貝,淺拷貝和Cloneable接口怎么用”,在日常操作中,相信很多人在Java深拷貝,淺拷貝和Cloneable接口怎么用問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Java深拷貝,淺拷貝和Cloneable接口怎么用”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

1. Cloneable接口的介紹

Cloneable是標(biāo)記型的接口(空接口),它們內(nèi)部都沒有方法和屬性,實(shí)現(xiàn) Cloneable來表示該對(duì)象能被克隆,能使用Object.clone()方法。如果沒有實(shí)現(xiàn) Cloneable的類對(duì)象調(diào)用clone()就會(huì)拋出CloneNotSupportedException異常。

Java深拷貝,淺拷貝和Cloneable接口怎么用

可以理解為Cloneable接口發(fā)揮的是標(biāo)記功能,自定義類型需要用戶自己標(biāo)記出哪些類是可以clone的,這個(gè)標(biāo)記就是去實(shí)現(xiàn)Cloneable接口,實(shí)現(xiàn)了Cloneable接口后就表明該類創(chuàng)建的對(duì)象可以被克隆。

而要想使一個(gè)類具備拷貝實(shí)例的功能,除了要實(shí)現(xiàn)Cloneable接口,還必須重寫Object類的clone()方法。

Java深拷貝,淺拷貝和Cloneable接口怎么用

可以看到Object類的clone()方法是被protected修飾的,所以需要在重寫的clone()方法中通過super關(guān)鍵字去調(diào)用Object類中的clone()方法

Java深拷貝,淺拷貝和Cloneable接口怎么用

2. 淺拷貝的介紹和實(shí)例

在拷貝一個(gè)對(duì)象時(shí),對(duì) 對(duì)象的基本數(shù)據(jù)類型的成員變量進(jìn)行拷貝,但對(duì)引用類型的成員變量只進(jìn)行引用的傳遞,并沒有創(chuàng)建一個(gè)新的對(duì)象,當(dāng)對(duì)引用類型的內(nèi)容修改會(huì)影響被拷貝的對(duì)象。簡(jiǎn)而言之:淺拷貝僅僅復(fù)制所拷貝的對(duì)象,而不復(fù)制它所引用的對(duì)象。

觀察下面的代碼,將Money類的實(shí)例作為了Person類的字段,new一個(gè)Person類的對(duì)象person1,將這個(gè)person1對(duì)象拷貝到person2中,這里的拷貝就是淺拷貝了,只是將person1對(duì)象的money引用拷貝到了person2,person1和person2中的momey指向的是同一個(gè)對(duì)象。

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修改前的結(jié)果");
        System.out.println(person1);
        System.out.println(person2);

        person2.money.m = 888;
        person2.id = 2;
        System.out.println("通過person2修改后的結(jié)果");
        System.out.println(person1);
        System.out.println(person2);
    }
}

執(zhí)行結(jié)果:

Java深拷貝,淺拷貝和Cloneable接口怎么用

淺拷貝圖解:

Java深拷貝,淺拷貝和Cloneable接口怎么用

3. 深拷貝的介紹和實(shí)例

在拷貝一個(gè)對(duì)象時(shí),除了對(duì)基本數(shù)據(jù)類型的成員變量進(jìn)行拷貝,對(duì)引用類型的成員變量進(jìn)行拷貝時(shí),創(chuàng)建一個(gè)新的對(duì)象來保存引用類型的成員變量。簡(jiǎn)而言之:深拷貝把要復(fù)制的對(duì)象所引用的對(duì)象都復(fù)制了一遍。

下面的代碼實(shí)現(xiàn)了深拷貝;實(shí)現(xiàn)person1對(duì)象的深拷貝,先用Person tmp引用來保存淺拷貝的結(jié)果,通過tmp引用找到money對(duì)象,再將money對(duì)象拷貝一份,然后賦值給tmp中的money,最后返回tmp即可。這樣就將money引用的對(duì)象也拷貝了一份,實(shí)現(xiàn)了深拷貝,此時(shí)person1和person2中的momey指向的是兩個(gè)不同的對(duì)象。

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修改前的結(jié)果");
        System.out.println(person1);
        System.out.println(person2);

        person2.money.m = 888;
        person2.id = 2;
        System.out.println("通過person2修改后的結(jié)果");
        System.out.println(person1);
        System.out.println(person2);
    }
}

執(zhí)行結(jié)果:

Java深拷貝,淺拷貝和Cloneable接口怎么用

深拷貝圖解:

Java深拷貝,淺拷貝和Cloneable接口怎么用

4. clone方法總結(jié)

java中clone方法是一個(gè)淺拷貝,引用類型依然在傳遞引用。我們可以通過繼續(xù)調(diào)用clone()方法,對(duì) 該對(duì)象的引用類型變量再實(shí)現(xiàn)一次clone()的方法來實(shí)現(xiàn)深拷貝。

到此,關(guān)于“Java深拷貝,淺拷貝和Cloneable接口怎么用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI