亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java?Cloneable接口的深拷貝與淺拷貝詳解

 更新時(shí)間:2022年03月17日 15:14:07   作者:似曾不相識  
這篇文章主要為大家詳細(xì)介紹了Java?Cloneable接口的深拷貝與淺拷貝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

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接口,那么也是無法正常克隆對象的

[原因:即使是反射性地調(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());
    }

在這里插入圖片描述

深拷貝案例

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

Pet類重寫clone()方法

在這里插入圖片描述

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

在這里插入圖片描述

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

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

在這里插入圖片描述

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!      

相關(guān)文章

  • Windows10系統(tǒng)下JDK1.8的下載安裝及環(huán)境變量配置的教程

    Windows10系統(tǒng)下JDK1.8的下載安裝及環(huán)境變量配置的教程

    這篇文章主要介紹了Windows10系統(tǒng)下JDK1.8的下載安裝及環(huán)境變量配置的教程,本文圖文并茂給大家介紹的非常詳細(xì),對大家的工作或?qū)W習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 用Java實(shí)現(xiàn)一個(gè)簡單的布隆過濾器

    用Java實(shí)現(xiàn)一個(gè)簡單的布隆過濾器

    這篇文章主要介紹了用Java實(shí)現(xiàn)一個(gè)簡單的布隆過濾器,布隆過濾器是1970年由布隆提出的,它實(shí)際上是一個(gè)很長的二進(jìn)制向量和一系列隨機(jī)映射函數(shù),布隆過濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中,需要的朋友可以參考下
    2023-12-12
  • java使用BeanUtils.copyProperties方法對象復(fù)制同名字段類型不同賦值為空問題解決方案

    java使用BeanUtils.copyProperties方法對象復(fù)制同名字段類型不同賦值為空問題解決方案

    這篇文章主要給大家介紹了關(guān)于java使用BeanUtils.copyProperties方法對象復(fù)制同名字段類型不同賦值為空問題的解決方案,文中通過代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-11-11
  • java實(shí)現(xiàn)飯店點(diǎn)菜系統(tǒng)

    java實(shí)現(xiàn)飯店點(diǎn)菜系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)飯店點(diǎn)菜系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 如何在JAVA中使用Synchronized

    如何在JAVA中使用Synchronized

    這篇文章主要介紹了如何在JAVA中使用Synchronized,文中代碼非常詳細(xì),對大家的學(xué)習(xí)有所幫助,感興趣的朋友可以參考下
    2020-06-06
  • SpringBoot中使用RocketMQ的示例代碼

    SpringBoot中使用RocketMQ的示例代碼

    本文主要介紹SpringBoot中使用RocketMQ的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • springboot接收日期類型參數(shù)的操作方法

    springboot接收日期類型參數(shù)的操作方法

    如果使用Get請求,直接使用對象接收,則可以使用@DateTimeFormat注解進(jìn)行格式化,本文重點(diǎn)給大家介紹springboot接收日期類型參數(shù)的方法,感興趣的朋友一起看看吧
    2024-02-02
  • Java多態(tài)性定義與用法實(shí)例詳解

    Java多態(tài)性定義與用法實(shí)例詳解

    這篇文章主要介紹了Java多態(tài)性定義與用法,較為詳細(xì)的分析了多態(tài)的概念、功能以及java定義與實(shí)現(xiàn)面向?qū)ο蠖鄳B(tài)性的相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09
  • sentinel整合ribbon與fallback流程分步講解

    sentinel整合ribbon與fallback流程分步講解

    這篇文章主要介紹了sentinel整合ribbon與fallback分步流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 微信公眾帳號開發(fā)-自定義菜單的創(chuàng)建及菜單事件響應(yīng)的實(shí)例

    微信公眾帳號開發(fā)-自定義菜單的創(chuàng)建及菜單事件響應(yīng)的實(shí)例

    本篇文章主要介紹了微信公眾帳號開發(fā)-自定義菜單的創(chuàng)建及菜單事件響應(yīng)的實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-12-12

最新評論