国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java中的淺克隆(shallow clone)與深克隆(deep clone)

2019-11-14 22:41:48
字體:
來源:轉載
供稿:網友
java中的淺克隆(shallow clone)與深克隆(deep clone)

Summary

淺克隆與深克隆對于JavaSE來說,是個難度系數比較低的概念,但不應該輕視它。

假設一個場景:對于某個list,代碼里并沒有任何對其的直接操作,但里面的元素的屬性卻被改變了,這可能就涉及到這個概念。

DescrOperator比較二者的地址會返回true。(不同引用,同一對象)

深克隆指則會copy一個新的對象并返回相應引用,即開辟了新的堆內存空間,因此使用“==” operator來比較兩者的地址時會返回false。(不同引用,不同對象)

淺克隆(shallow clone)

  1. clone對象是實例對象時,使用“=”操作符進行淺克隆。
  2. clone對象是對象數組的元素時,使用 System.arraycoppy() 進行淺克隆。(你非得要用"=" foreach地clone也沒人攔著)

jdk中顯式定義的clone操作基本上都使用:

1 System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

例如ArrayList中的clone()、Arrays.copyOf()等對具體數組的clone其實底層都是調用該方法。

 1 package com.scv.test.clone; 2  3 public class ShallowCloneTest { 4  5     public static void main(String[] args) throws Exception { 6         Zerg z0 = new Zerg(); 7         Zerg z1 = z0; 8         System.out.驗證Shallow Clone

深克隆(deep clone)

jdk中并沒有顯式定義深克隆,或者說并沒有直接提供工具類來進行。要讓你的自定義類支持深克隆,必須具備兩個條件:

  1. implements Cloneable interface.
  2. override clone() defined in java.lang.Object.

如果不實現Cloneable而直接override Object的clone(),則會拋出CloneNotSupportedException。

 1 package com.scv.test.clone; 2  3 public class DeepCloneTest { 4  5     public static void main(String[] args) throws Exception { 6         CloneableZerg z0 = new CloneableZerg(); 7         CloneableZerg z1 = z0.clone(); 8          9         System.out.println("0. " + (z0 == z1));10     }11     12 }13 14 class CloneableZerg implements Cloneable{15     16     @Override17     public CloneableZerg clone() throws CloneNotSupportedException{18         return (CloneableZerg)super.clone();19     }20 }21 22 /* Output:23 0. false24 */
驗證Deep Clone

實際上,你可以自定義哪些成員變量(field)允許clone,哪些不允許(有點transient的感覺?)。

jdk中的實現:ArrayList中的淺克隆與深克隆

 1 package com.scv.test.clone; 2  3 import java.util.ArrayList; 4  5 public class ArrayListCloneTest { 6  7     public static void main(String[] args) throws Exception { 8         CloneTarget t = new CloneTarget(); 9         10         ArrayList<CloneTarget> list0 = new ArrayList<CloneTarget>(1);11         list0.add(t);12         ArrayList<CloneTarget> list1 = (ArrayList<CloneTarget>) list0.clone();13         list0.get(0).setFieldA(20);14         15         System.out.println("0. " + (list0 == list1));16         System.out.println("1. " + (list0.get(0) == list1.get(0)));17         System.out.println("2. " + list1.get(0).getFieldA());18     }19     20 }21 22 class CloneTarget implements Cloneable{23     24     private int fieldA = 10;25     26     @Override27     public CloneTarget clone() throws CloneNotSupportedException{28         return (CloneTarget)super.clone();29     }30     31     public void setFieldA(int a){32         fieldA = a;33     }34     35     public int getFieldA(){36         return fieldA;37     }38 }39 40 /*41  * Output:42  * 0. false 43  * 1. true44  * 2. 2045 */
Click Me

操作說明:

  1. 創建一個ArrayList對象list0
  2. list0中加入一個對象t
  3. 克隆list0對象為list1
  4. 再修改list0中元素(即t)的屬性

結果說明:

  1. ArrayList實現了Cloneable接口,arraylist.clone()為深克隆,故list0與list1分別指向不同內存區域。
  2. ArrayList對象的clone()對于內部數組的元素僅為淺克隆,故list0中的元素(t)與list1中的元素為同一個,對list0元素的修改將影響到list1的元素。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 资中县| 灵武市| 鹤峰县| 新干县| 德钦县| 依安县| 塔城市| 翁源县| 浦江县| 岳阳市| 马尔康县| 青海省| 长兴县| 宁津县| 揭东县| 德格县| 黎平县| 九寨沟县| 茂名市| 德安县| 慈溪市| 轮台县| 古田县| 丰原市| 盐源县| 玛曲县| 寻甸| 上饶市| 玉溪市| 板桥市| 长海县| 清流县| 寿光市| 永吉县| 柳河县| 镇巴县| 濉溪县| 都江堰市| 门源| 肥乡县| 西丰县|