溫馨提示×

溫馨提示×

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

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

Java?Cloneable接口的深拷貝與淺拷貝方法

發(fā)布時(shí)間:2022-03-17 17:08:47 來源:億速云 閱讀:149 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“Java Cloneable接口的深拷貝與淺拷貝方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java Cloneable接口的深拷貝與淺拷貝方法”吧!

    Cloneable接口源碼

    Cloneable接口:

    實(shí)現(xiàn)此接口的類——可被推斷java.lang.Object的clone()方法可以被合法調(diào)用-以實(shí)現(xiàn)類實(shí)例:屬性到屬性的拷貝。

    如果一個(gè)類未實(shí)現(xiàn)Cloneable接口,那么調(diào)用clone()方法時(shí),會拋出CloneNotSupportedException異常。

    通常,實(shí)現(xiàn)了Cloneable接口的子類,應(yīng)當(dāng)以public訪問權(quán)限重寫clone()方法(盡管java.Object類中的clone方法是protected類型的)

    應(yīng)當(dāng)認(rèn)識到:Cloneable接口沒有包含clone()方法,因此,如果僅僅是implements了Cloneable接口,那么也是無法正??寺ο蟮?/p>

    [原因:即使是反射性地調(diào)用了克隆方法,也不能保證它一定會成功]——個(gè)人理解就是:是否重寫Clone()方法、或者“淺拷貝與深拷貝”問題的存在所導(dǎo)致的。

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    淺拷貝案例

    Pet類定義

    注意到:Pet類實(shí)現(xiàn)了Cloneable接口,但是沒有重寫Clone()方法(顯然:此時(shí)Pet類不具備對象克隆的能力)。

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    Person類定義

    注意到:Person類實(shí)現(xiàn)了Cloneable接口,也重寫Clone()方法。那么,是否Person類就具備了對象克隆的能力呢?(由于淺拷貝問題的存在,認(rèn)為這種對象克隆能力是不完整的、有缺陷的)。

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    淺拷貝問題-代碼測試

    為什么說:此時(shí)Person類的對象克隆能力是不完整的、有缺陷的?因?yàn)榇藭r(shí),在通過Person對象調(diào)用clone()方法,克隆對象時(shí),其成員屬性pet(Pet類的對象)值的克隆,僅僅是對堆區(qū)內(nèi)存地址的簡單拷貝。

    即:說白了,Person對象和克隆出來的對象,其pet屬性值共享同一塊堆區(qū)內(nèi)存。——問題顯而易見:當(dāng)對克隆出來的對象的pet屬性進(jìn)行set操作時(shí),顯然會影響到原始Person對象的pet屬性值。

    代碼演示如下:

      //methods
        public static void main(String[] args) throws CloneNotSupportedException {
            testPerson();
        }
        public static void testPerson() throws CloneNotSupportedException {
            Person p=new Person("張三",14,new Pet("小黑"));
            System.out.println(p);
            Person clone = (Person)p.clone();
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println(p.getPet()==clone.getPet());
            System.out.println("************");
            clone.setAge(15);
            System.out.println(p);
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println("************");
            clone.getPet().setName("小黃");
            System.out.println(p);
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println(p.getPet()==clone.getPet());
        }

    Java?Cloneable接口的深拷貝與淺拷貝方法

    深拷貝案例

    那么,如何實(shí)現(xiàn)深拷貝呢?關(guān)鍵就在上述案例中,被注釋的幾行代碼中。

    Pet類重寫clone()方法

    Java?Cloneable接口的深拷貝與淺拷貝方法

    Person的clone()方法中調(diào)用Pet的clone方法

    Java?Cloneable接口的深拷貝與淺拷貝方法

    淺拷貝問題解決-深拷貝代碼測試

    測試代碼不變,再次運(yùn)行:

    Java?Cloneable接口的深拷貝與淺拷貝方法

    到此,相信大家對“Java Cloneable接口的深拷貝與淺拷貝方法”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

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

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

    AI