欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Java深拷貝,淺拷貝和Cloneable接口

 更新時(shí)間:2022年08月21日 14:35:49   作者:XIN-XIANG榮  
這篇文章主要為大家詳細(xì)介紹了Java中Cloneable接口以及深拷貝與淺拷貝的相關(guān)知識(shí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

1. Cloneable接口的介紹

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

可以理解為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接口,還必須重寫(xiě)Object類的clone()方法。

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

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

在拷貝一個(gè)對(duì)象時(shí),對(duì) 對(duì)象的基本數(shù)據(jù)類型的成員變量進(jìn)行拷貝,但對(duì)引用類型的成員變量只進(jìn)行引用的傳遞,并沒(méi)有創(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("通過(guò)person2修改前的結(jié)果");
        System.out.println(person1);
        System.out.println(person2);

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

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

淺拷貝圖解:

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

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

下面的代碼實(shí)現(xiàn)了深拷貝;實(shí)現(xiàn)person1對(duì)象的深拷貝,先用Person tmp引用來(lái)保存淺拷貝的結(jié)果,通過(guò)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("通過(guò)person2修改前的結(jié)果");
        System.out.println(person1);
        System.out.println(person2);

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

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

深拷貝圖解:

4. clone方法總結(jié)

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

到此這篇關(guān)于詳解Java深拷貝,淺拷貝和Cloneable接口的文章就介紹到這了,更多相關(guān)Java Cloneable接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 微服務(wù)SpringBoot整合Jasypt加密工具的場(chǎng)景分析

    微服務(wù)SpringBoot整合Jasypt加密工具的場(chǎng)景分析

    Jasypt是Java加密工具包,能支持對(duì)密碼的哈希加密,對(duì)文本和二進(jìn)制數(shù)據(jù)的對(duì)稱加解密,還能集成SpringBoot項(xiàng)目對(duì)配置文件中的密鑰進(jìn)行加密存儲(chǔ),這篇文章主要介紹了微服務(wù)SpringBoot整合Jasypt加密工具,需要的朋友可以參考下
    2022-10-10
  • Java實(shí)現(xiàn)多個(gè)wav文件合成一個(gè)的方法示例

    Java實(shí)現(xiàn)多個(gè)wav文件合成一個(gè)的方法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)多個(gè)wav文件合成一個(gè)的方法,涉及java文件流讀寫(xiě)、編碼轉(zhuǎn)換、解析等相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • Maven 安裝目錄的詳細(xì)介紹

    Maven 安裝目錄的詳細(xì)介紹

    這篇文章主要介紹了Maven 安裝目錄的詳細(xì)介紹的相關(guān)資料,這里對(duì)Maven進(jìn)行了解讀,希望通過(guò)本文可以幫助到大家,需要的朋友可以參考下
    2017-08-08
  • Spring Boot 2.X優(yōu)雅的解決跨域問(wèn)題

    Spring Boot 2.X優(yōu)雅的解決跨域問(wèn)題

    這篇文章主要給大家介紹了關(guān)于Spring Boot 2.X如何優(yōu)雅的解決跨域問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot 2.X具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java異常體系非正常停止和分類

    Java異常體系非正常停止和分類

    這篇文章主要介紹了Java異常體系非正常停止和分類,指的是程序在執(zhí)行過(guò)程中,出現(xiàn)的非正常的情況,最終會(huì)導(dǎo)致JVM的非正常停止更多相關(guān)內(nèi)容需要的朋友可以參考一下
    2022-06-06
  • Java中判斷對(duì)象是否相等的equals()方法使用教程

    Java中判斷對(duì)象是否相等的equals()方法使用教程

    與==運(yùn)算符響應(yīng),equals()方法也是Java中對(duì)對(duì)象進(jìn)行比較的一大方式,要特別注意二者的不同點(diǎn),這個(gè)我們?cè)谙挛闹屑磳⒅v到,接下來(lái)我們就來(lái)看一下Java中判斷對(duì)象是否相等的equals()方法使用教程
    2016-05-05
  • 通過(guò)Java帶你了解網(wǎng)絡(luò)IO模型

    通過(guò)Java帶你了解網(wǎng)絡(luò)IO模型

    這篇文章將通過(guò)Java帶大家了解網(wǎng)絡(luò)IO模型,包括BIO,NoBlockingIO,NIO(NewIO),AIO等做了詳細(xì)得介紹,感興趣的小伙伴可以參考閱讀本文
    2023-05-05
  • Spring?Security?OAuth?Client配置加載源碼解析

    Spring?Security?OAuth?Client配置加載源碼解析

    這篇文章主要為大家介紹了Spring?Security?OAuth?Client配置加載源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • spring解決循環(huán)依賴的方案示例

    spring解決循環(huán)依賴的方案示例

    這篇文章主要介紹spring如何解決循環(huán)依賴,文中有相關(guān)的代碼示例給大家參考,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的同學(xué)可以借鑒閱讀
    2023-05-05
  • 使用ScheduledThreadPoolExecutor踩過(guò)最痛的坑

    使用ScheduledThreadPoolExecutor踩過(guò)最痛的坑

    這篇文章主要介紹了使用ScheduledThreadPoolExecutor踩過(guò)最痛的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評(píng)論