溫馨提示×

溫馨提示×

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

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

Java中淺復(fù)制和深復(fù)制的區(qū)別是什么

發(fā)布時(shí)間:2020-06-24 09:11:39 來源:億速云 閱讀:416 作者:Leah 欄目:編程語言

Java中淺復(fù)制和深復(fù)制的區(qū)別是什么?可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

將一個(gè)對(duì)象的引用復(fù)制給另一個(gè)對(duì)象,一共有三種方式。第一種方式是直接賦值,第二種方式是淺復(fù)制,第三種方式是深復(fù)制。

1.直接賦值

在Java中,A a1 = a2,這實(shí)際上復(fù)制的是引用,也就是說 a1 和 a2指向的是同一個(gè)對(duì)象。因此,當(dāng)a1變化時(shí),a2里面的成員變量也會(huì)跟著變化。

2.淺復(fù)制(復(fù)制引用但不復(fù)制引用的對(duì)象)

淺復(fù)制,又稱為淺拷貝。創(chuàng)建一個(gè)新對(duì)象,然后將當(dāng)前對(duì)象非靜態(tài)字段復(fù)制到該新對(duì)象,如果字段是值類型的,那么對(duì)該字段執(zhí)行復(fù)制;如果該字段時(shí)引用類型的話,則復(fù)制引用但不復(fù)制引用的對(duì)象。因此,原始對(duì)象及其副本引用同一個(gè)對(duì)象。

class Resume implements Cloneable{ 
     public Object clone() { 
         try { 
             return (Resume)super.clone(); 
         } catch (Exception e) { 
             e.printStackTrace(); 
         return null; 
         } 
     } 
}

3.深復(fù)制(復(fù)制對(duì)象和其引用對(duì)象)

又稱深拷貝,不僅復(fù)制對(duì)象本身,而且復(fù)制對(duì)象包含的引用指向的所有對(duì)象。

class Student implements Cloneable {
         String name;
         int age;
         Professor p;
     Student(String name, int age, Professor p) {
         this.name = name;
         this.age = age;
         this.p = p;
     }
     public Object clone() {
         Student o = null;
         try {
             o = (Student) super.clone();
         } catch (CloneNotSupportedException e) {
             System.out.println(e.toString());
         }
     o.p = (Professor) p.clone();
     return o;
     }
}

使用clone()方法克隆一個(gè)對(duì)象的步驟:

1)被克隆的類要實(shí)現(xiàn)Cloneable接口。

2)被克隆的類要重寫clone()方法。

那么在編程時(shí),如何選擇使用哪種復(fù)制方式呢?首先,檢查類有無非基本類型(即對(duì)象)的數(shù)據(jù)成員。若沒有,則返回super.clone()即可。若有,確保類中包含的所有非基本類型的成員變量都實(shí)現(xiàn)了深復(fù)制。

引申:淺復(fù)制與深復(fù)制的區(qū)別?

淺復(fù)制(Shallow Clone):被復(fù)制的對(duì)象的所有變量都含有與原來對(duì)象相同的值,而所有其他對(duì)象的引用仍然指向原來的對(duì)象。換而言之,淺復(fù)制僅僅復(fù)制所考慮的對(duì)象,而不復(fù)制它引用的對(duì)象。

深復(fù)制(Deep Clone):被復(fù)制對(duì)象的所有變量都含有與原來對(duì)象相同的值,除去那些引用其他對(duì)象的變量。那些引用其他對(duì)象的變量將指向被復(fù)制的新對(duì)象,而不是原有的那些被引用的對(duì)象。換而言之,深復(fù)制把復(fù)制的對(duì)象所引用的對(duì)象都復(fù)制了一遍。

擴(kuò)展:

原型模式主要用于對(duì)象的復(fù)制,實(shí)現(xiàn)了接口(實(shí)現(xiàn)Cloneable接口),重寫一個(gè)方法(重寫Object類中的clone()方法),即完成了原型模式。

原型模式中的拷貝分為“淺拷貝”和“深拷貝”:

淺拷貝:對(duì)值類型的成員變量進(jìn)行值的復(fù)制,對(duì)引用類型得成員變量只復(fù)制引用,不復(fù)制引用的對(duì)象。

拷貝:對(duì)值類型的成員變量進(jìn)行值的復(fù)制,對(duì)引用類型的成員變量也進(jìn)行引用對(duì)象的復(fù)制。

(Object類的clone方法只會(huì)拷貝對(duì)象中的基本數(shù)據(jù)類型的值,對(duì)于數(shù)組、容器對(duì)象、引用對(duì)象等都不會(huì)拷貝,這就是淺拷貝。如果要實(shí)現(xiàn)深拷貝,必須將原型模式中的數(shù)組、容器對(duì)象、引用對(duì)象等另行拷貝。)

原型模式的優(yōu)點(diǎn):

1.如果創(chuàng)建新的對(duì)象比較復(fù)雜時(shí),可以利用原型模式簡化對(duì)象的創(chuàng)建過程。

2.是永遠(yuǎn)是模式創(chuàng)建對(duì)象比直接new一個(gè)對(duì)象在性能上要好得多,因?yàn)镺bject類的clone方法是一個(gè)本地方法,它直接操作內(nèi)存中的二進(jìn)制流,特別是復(fù)制大對(duì)象時(shí),性能的差別非常明顯。

原型模式的使用場景:

因?yàn)橐陨蟽?yōu)點(diǎn),所以在需要重復(fù)地創(chuàng)建相似對(duì)象時(shí)可以考慮使用原型模式。比如需要在一個(gè)循環(huán)體內(nèi)創(chuàng)建對(duì)象,假如對(duì)象創(chuàng)建過程比較復(fù)雜或者循環(huán)次數(shù)很多的話,使用原型模式不但可以簡化創(chuàng)建過程,而且可以使系統(tǒng)的整體性能提高很多。

看完上述內(nèi)容,你們對(duì)Java中淺復(fù)制和深復(fù)制的區(qū)別有進(jìn)一步的了解嗎?如果還想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀。

向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