最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java對(duì)象克隆實(shí)現(xiàn)方法詳解

 更新時(shí)間:2023年06月26日 11:17:54   作者:暴走的小帥  
這篇文章主要給大家介紹了關(guān)于java對(duì)象克隆實(shí)現(xiàn)的相關(guān)資料,克隆就是復(fù)制一個(gè)對(duì)象的副本,Java支持我們對(duì)一個(gè)對(duì)象進(jìn)行克隆,通常用在裝飾模式和原型模式中,需要的朋友可以參考下

概述:

當(dāng)我們new一個(gè)對(duì)象時(shí),其中的屬性就會(huì)被初始化, 那么想要保存剛開始初始化的值就靠clone方法來實(shí)現(xiàn), 平時(shí)我們最常見的是一個(gè)對(duì)象的引用指向另一個(gè)對(duì)象,并不是創(chuàng)建了兩個(gè)對(duì)象.

 Person p1 = new Person(100,"jim");
        Person p2 = p1;
        System.out.println(p1==p2);//true

克隆肯定是創(chuàng)建了兩個(gè)對(duì)象

 Person p1 = new Person(100,"jim");
        Person p2 =p1.clone();//克隆的新對(duì)象
        System.out.println(p1==p2);//false

克隆分為淺克隆(ShallowClone)和深克隆(DeepClone)。

在 Java 語言中,數(shù)據(jù)類型分為值類型(基本數(shù)據(jù)類型)和引用類型,值類型包括 int、double、byte、boolean、char 等簡(jiǎn)單數(shù)據(jù)類型,引用類型包括類、接口、數(shù)組等復(fù)雜類型?;绢愋偷闹悼梢灾苯訌?fù)制,引用類型只能復(fù)制引用地址。所以淺克隆和深克隆的主要區(qū)別在于是否支持引用類型的成員變量的復(fù)

制.

淺克隆

在淺克隆中,如果原型對(duì)象的成員變量是值類型,將復(fù)制一份給克隆對(duì)象;如果原型對(duì)象的成員變量是引用類型,則將引用對(duì)象的地址復(fù)制一份給克隆對(duì)象,也就是說原型對(duì)象和克隆對(duì)象的成員變量指向相同的內(nèi)存地址。簡(jiǎn)單來說,在淺克隆中,當(dāng)對(duì)象被復(fù)制時(shí)只復(fù)制它本身和其中包含的值類型的成員變量,而引用類型的成員對(duì)象并沒有復(fù)制。

實(shí)現(xiàn)方式:

1.在 Java 語言中,通過覆蓋 Object 類的 clone()方法可以實(shí)現(xiàn)淺克隆。

2.在 spring 框架中提供 BeanUtils.copyProperties(source,target);

這里我們主要演示通過重寫object中clone方法來實(shí)現(xiàn)

1.首先定義一個(gè)類(需要被克隆的類)

public class Person implements  Cloneable{
     int num;
     String name;
     Address address;
    public Person() {
    }
    public Person(int num, String name) {
        this.num = num;
        this.name = name;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person person = (Person)super.clone();
        return person;
    }
    @Override
    public String toString() {
        return "Person{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

2.可以看到Person類關(guān)聯(lián)著Address類,也寫出來

public class Address  {
     String  address;
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
}

3.寫一個(gè)Test類進(jìn)行測(cè)試

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address();
                address.setAddress("漢中");
        Person p1 = new  Person(100,"jim");
               p1.setAddress(address);
        Person p2 =p1.clone();
               p2.setName("tom");
               address.setAddress("西安");
        System.out.println(p1); // jim   西安
        System.out.println(p2);// tom    西安
    }
}

首先看name屬性,p1的name為jim,克隆出另一個(gè)對(duì)象p2,將name改成了tom,因?yàn)槭莾蓚€(gè)對(duì)象,所以輸出的結(jié)果分別都不同.

再看關(guān)聯(lián)對(duì)象, 首先將有漢中信息的address加入到了p1中,所以目前p1中的address是漢中,經(jīng)過克隆出p2后,其實(shí)對(duì)于address來說只克隆了地址,所以說p1和p2指向的都是同一個(gè)address,所以都是漢中,再經(jīng)過一次修改成了西安,所以都是西安.

所以說淺克隆只是克隆了引用類型變量的地址.

深克隆

在深克隆中,無論原型對(duì)象的成員變量是值類型還是引用類型,都將復(fù)制一份給克隆對(duì)象,深克隆將原型對(duì)象的所有引用對(duì)象也復(fù)制一份給克隆對(duì)象。簡(jiǎn)單來說,在深克隆中,除了對(duì)象本身被復(fù)制外,對(duì)象所包含的所有成員變量也將復(fù)制

在 Java 語言中,如果需要實(shí)現(xiàn)深克隆,可以通過覆蓋 Object 類的 clone()方法實(shí)現(xiàn),也可以通過序列化(Serialization)等方式來實(shí)現(xiàn)。序列化就是將對(duì)象寫到流的過程,寫到流中的對(duì)象是原有對(duì)象的一個(gè)拷貝,而原對(duì)象仍然存在于內(nèi)存中。通過序列化實(shí)現(xiàn)的拷貝不僅可以復(fù)制對(duì)象本身,而且可以復(fù)制其引用的成員對(duì)象,因此通過序列化將對(duì)象寫到一個(gè)流中,再從流里將其讀出來,可以實(shí)現(xiàn)深克隆。需要注意的是能夠?qū)崿F(xiàn)序列化的對(duì)象其類必須實(shí)現(xiàn)Serializable 接口,否則無法實(shí)現(xiàn)序列化操作

1.重寫Object類中的clone方法

1.首先定義一個(gè)類(需要被克隆的類),相比于上面的淺克隆增加了一行克隆address對(duì)象的代碼

public class Person implements  Cloneable{
     int num;
     String name;
     Address address;
    public Person() {
    }
    public Person(int num, String name) {
        this.num = num;
        this.name = name;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person person = (Person)super.clone();
        person.address = (Address)address.clone();   //深度復(fù)制  聯(lián)同person中關(guān)聯(lián)的對(duì)象也一同克隆.
        return person;
    }
    @Override
    public String toString() {
        return "Person{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

2.Address寫出來,相比于上面淺克隆多了一個(gè)重寫Object類的clone方法

public class Address  {
     String  address;
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
   @Override
    protected Address clone() throws CloneNotSupportedException {
        return (Address)super.clone();
    }
}

3.還是Test測(cè)試類

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address();
                address.setAddress("漢中");
        Person p1 = new  Person(100,"jim");
               p1.setAddress(address);
        Person p2 =p1.clone();
               p2.setName("tom");
               address.setAddress("西安");
        System.out.println(p1); // jim   西安
        System.out.println(p2);// tom    漢中
    }
}

這次的結(jié)果會(huì)有所不同, 因?yàn)樯羁寺〔粌H克隆了自己, 還克隆了關(guān)聯(lián)著的類的對(duì)象, 所以說原來的p1存儲(chǔ)的漢中被克隆在了p2中,而最后一行更改為西安的是原來的address對(duì)象, p2中已經(jīng)克隆了原來的address并且保存了下來

2.序列化(Serialization)的方式

如果需要被克隆的類中關(guān)聯(lián)的其他類的對(duì)象太多, 那么繼續(xù)用深克隆的話需要耗費(fèi)大量的時(shí)間去一個(gè)一個(gè)克隆關(guān)聯(lián)著的對(duì)象, 而序列化的方式可以將該類中所有關(guān)聯(lián)的對(duì)象化成流從而高校的進(jìn)行克隆.

1.還是創(chuàng)建一個(gè)關(guān)聯(lián)著被克隆的類的對(duì)象

public class Address  implements Serializable {
     String  address;
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
}

2.Person類,里面寫一個(gè)自己的序列化方式的克隆方法

public class Person implements Serializable {
     int num;
     String name;
     Address address;
    public Person() {
    }
    public Person(int num, String name) {
        this.num = num;
        this.name = name;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    /**
     * 自定義克隆方法
     * @return
     */
    public Person myclone() {
            Person person = null;
              try { // 將該對(duì)象序列化成流,因?yàn)閷懺诹骼锏氖菍?duì)象的一個(gè)拷貝,而原對(duì)象仍然存在于JVM里面。所以利用這個(gè)特性可以實(shí)現(xiàn)對(duì)象的深拷貝
                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
                      ObjectOutputStream oos = new ObjectOutputStream(baos);
                      oos.writeObject(this);
            // 將流序列化成對(duì)象
                    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                     ObjectInputStream ois = new ObjectInputStream(bais);
                     person = (Person) ois.readObject();
                  } catch (IOException e) {
                     e.printStackTrace();
                  } catch (ClassNotFoundException e) {
                     e.printStackTrace();
                 }
             return person;
          }
    @Override
    public String toString() {
        return "Person{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

3.Test類測(cè)試

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Address address = new Address();
                address.setAddress("漢中");
        Person p1 = new  Person(100,"jim");
        p1.setAddress(address);
        Person p2 =p1.myclone();
               p2.setName("tom");
               address.setAddress("西安");
        System.out.println(p1);jim   西安
        System.out.println(p2);tom   漢中
    }
}

所以說, 得看具體情況進(jìn)行選擇

總結(jié)

到此這篇關(guān)于java對(duì)象克隆實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)java對(duì)象克隆內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java集合源碼全面分析

    Java集合源碼全面分析

    下面小編就為大家?guī)硪黄狫ava集合源碼全面分析。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-07-07
  • Spring Cloud實(shí)現(xiàn)跨語言微服務(wù)通信的三種方案

    Spring Cloud實(shí)現(xiàn)跨語言微服務(wù)通信的三種方案

    本文深入探討Spring Cloud實(shí)現(xiàn)跨語言微服務(wù)通信的三大核心方案: Sidecar模式:通過代理非Java服務(wù),性能提升5倍,延遲從150ms降至30ms ASM+MSE方案:結(jié)合阿里云服務(wù)網(wǎng)格,吞吐量提升3倍至2400TPS Feign+自定義序列化,需要的朋友可以參考下
    2026-05-05
  • Java從零編寫汽車租賃系統(tǒng)全程分析

    Java從零編寫汽車租賃系統(tǒng)全程分析

    這篇文章介紹了Java實(shí)現(xiàn)汽車租賃系統(tǒng)的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • Java基礎(chǔ)教程之繼承詳解

    Java基礎(chǔ)教程之繼承詳解

    這篇文章主要介紹了Java基礎(chǔ)教程之繼承詳解,繼承是除組合(composition)之外,提高代碼重復(fù)可用性(reusibility)的另一種重要方式,本文對(duì)繼承做了詳細(xì)講解,需要的朋友可以參考下
    2014-08-08
  • mybatis中關(guān)于type-aliases-package的使用

    mybatis中關(guān)于type-aliases-package的使用

    這篇文章主要介紹了mybatis中關(guān)于type-aliases-package的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java中的Unsafe工具類使用詳解

    Java中的Unsafe工具類使用詳解

    這篇文章主要介紹了Java中的Unsafe工具類使用詳解,Unsafe是jdk提供的一個(gè)直接訪問操作系統(tǒng)資源的工具類(底層c++實(shí)現(xiàn)),它可以直接分配內(nèi)存,內(nèi)存復(fù)制,copy,提供cpu級(jí)別的CAS樂觀鎖等操作,需要的朋友可以參考下
    2023-12-12
  • 淺析java 希爾排序(Shell)算法

    淺析java 希爾排序(Shell)算法

    這篇文章主要介紹了淺析java 希爾排序(Shell)算法的原理以及示例,需要的朋友可以參考下
    2015-02-02
  • 詳解分別用Kotlin和java寫RecyclerView的示例

    詳解分別用Kotlin和java寫RecyclerView的示例

    本篇文章主要介紹了詳解分別用Kotlin和java寫RecyclerView的示例,詳解分別用Kotlin和java寫RecyclerView的示例
    2017-12-12
  • Java對(duì)xls文件進(jìn)行讀寫操作示例代碼

    Java對(duì)xls文件進(jìn)行讀寫操作示例代碼

    Java開發(fā)項(xiàng)目中經(jīng)常會(huì)碰到處理Excel文件中數(shù)據(jù)的情況,下面這篇文章主要給大家介紹了利用Java對(duì)xls文件進(jìn)行讀寫操作的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-08-08
  • 基于ScheduledExecutorService的兩種方法(詳解)

    基于ScheduledExecutorService的兩種方法(詳解)

    下面小編就為大家?guī)硪黄赟cheduledExecutorService的兩種方法(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10

最新評(píng)論

沂南县| 叙永县| 阳江市| 汉沽区| 延寿县| 英吉沙县| 宁夏| 筠连县| 马龙县| 巴林右旗| 宁海县| 饶阳县| 措美县| 巩义市| 外汇| 唐河县| 庄浪县| 克东县| 龙南县| 双牌县| 武清区| 四子王旗| 抚顺市| 溆浦县| 新乡市| 酒泉市| 宜川县| 车致| 赤城县| 鄂托克前旗| 亳州市| 鹿邑县| 徐州市| 江川县| 乐山市| 泗阳县| 印江| 房产| 邵东县| 泽普县| 土默特右旗|