<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JAVA 對象拷貝

    為什么需要有對象拷貝?

    對象拷貝相對的自然是引用拷貝。java初學者經常會問,我這個方法要改變一個對象的屬性,可以把參數傳進去了,為什么沒有改變了?

    ——基本數據類型傳值,而對象傳引用或引用的拷貝。

    而有時候我們要獲取到一個當前狀態的對象復制品,他們是兩個獨立對象。不再是引用或者引用拷貝(實質都是指向對象本身)。就是說a是b的拷貝,b發生變化的時候,不要影響a。


    對象拷貝有淺拷貝和深度拷貝兩種。

    1)淺拷貝

    淺拷貝是指對象中基本數據類型得到拷貝,而引用數據類型并未拷貝。
    提到拷貝自然和clone聯系起來了,所有具有clone功能的類都有一個特性,那就是它直接或間接地實現了Cloneable接口。
    否則,我們在嘗試調用clone()方法時,將會觸發CloneNotSupportedException異常。
    eg:

    ?1 public ? class ?DOG? implements ?Cloneable
    ?2 {
    ?3 ???? public ?DOG(String?name,? int ?age)
    ?4 ???? {
    ?5 ???????? this .name? = ?name;
    ?6 ???????? this .age? = ?age;
    ?7 ????}

    ?8
    ?9 ???? public ?String?getName()
    10 ???? {
    11 ???????? return ? this .name;
    12 ????}

    13
    14 ???? public ? int ?getAge()
    15 ???? {
    16 ???????? return ? this .age;
    17 ????}

    18
    19 ???? public ?Object?clone()
    20 ???? {
    21 ???????? try
    22 ???????? {
    23 ???????????? return ? super .clone();
    24
    25 ????????}
    ? catch ?(CloneNotSupportedException?e)
    26 ???????? {
    27 ???????????? return ? null ;
    28 ????????}

    29 ????}

    30
    31 ???? public ?String?name;
    32
    33 ???? private ? int ?age;
    34
    35 ???? // test
    36 ???? public ? static ? void ?main(String[]?args)
    37 ???? {
    38 ????????DOG?dog1? = ? new ?DOG( " xiaogou " ,? 2 );
    39 ????????DOG?dog2? = ?(DOG)?dog1.clone();
    40 ????????dog1.name? = ? " dagou " ;
    41 ????????System.out.println(dog2.getName());
    42 ????????System.out.println(dog2.getAge());
    43 ????????System.out.println(dog1.getName());
    44 ????????System.out.println(dog1.getAge());
    45
    46 ????}

    47
    48 }

    49



    運行結果:

    xiaogou
    2
    dagou
    2

    2)深度拷貝

    相對淺拷貝。實現對象中基本數據類型和引用數據類型的拷貝。

    請先看下面代碼:

    ?

    ?1 class ?AAA
    ?2 {
    ?3 ???? public ?AAA(String?name)
    ?4 ???? {
    ?5 ???????? this .name? = ?name;
    ?6 ????}

    ?7
    ?8 ???? public ?String?name;
    ?9 }

    10
    11 class ?DOG? implements ?Cloneable
    12 {
    13 ???? public ?DOG(String?name,? int ?age,?AAA?birthday)
    14 ???? {
    15 ???????? this .name? = ?name;
    16 ???????? this .age? = ?age;
    17 ???????? this .birthday? = ?birthday;
    18 ????}

    19
    20 ???? public ?String?getName()
    21 ???? {
    22 ???????? return ?name;
    23 ????}

    24
    25 ???? public ? int ?getAge()
    26 ???? {
    27 ???????? return ?age;
    28 ????}

    29
    30 ???? public ?AAA?getBirthday()
    31 ???? {
    32 ???????? return ?birthday;
    33 ????}

    34
    35 ???? public ?String?getBirth(AAA?a)
    36 ???? {
    37 ???????? return ?a.name;
    38 ????}

    39
    40 ???? public ?String?name;
    41
    42 ???? private ? int ?age;
    43
    44 ???? public ?AAA?birthday;
    45
    46 ???? public ?Object?clone()
    47 ???? {
    48 ???????? try
    49 ???????? {
    50 ???????????? super .clone();
    51 ???????????? return ? super .clone();
    52 ????????}
    ? catch ?(Exception?e)
    53 ???????? {
    54 ???????????? return ? null ;
    55 ????????}

    56 ????}

    57 }

    58
    59 public ? class ?TestClone
    60 {
    61 ???? public ? static ? void ?main(String[]?args)
    62 ???? {
    63 ????????AAA?Day? = ? new ?AAA( " test " );
    64 ????????DOG?dog1? = ? new ?DOG( " xiaogou " ,? 2 ,?Day);
    65 ????????DOG?dog2? = ?(DOG)?dog1.clone();
    66 ???????? // ??dog2.birthday?=?(AAA)?dog1.birthday.clone();?
    67 ????????dog1.birthday.name? = ? " 333 " ;
    68 ????????System.out.println(dog1.getBirth(dog1.birthday));
    69 ????????System.out.println(dog2.getBirth(dog2.birthday));
    70 ????}

    71 }

    72


    運行結果是:
    333
    333
    而真正要實現拷貝還的加點代碼,如下請對比上面和下面代碼的異同之處:

    ?1 class ?AAA? implements ?Cloneable
    ?2 {
    ?3 ???? public ?AAA(String?name)
    ?4 ???? {
    ?5 ???????? this .name? = ?name;
    ?6 ????}

    ?7
    ?8 ???? public ?Object?clone()
    ?9 ???? {
    10 ???????? try
    11 ???????? {
    12 ???????????? super .clone();
    13 ???????????? return ? super .clone();
    14 ????????}
    ? catch ?(Exception?e)
    15 ???????? {
    16 ???????????? return ? null ;
    17 ????????}

    18 ????}

    19
    20 ???? public ?String?name;
    21 }

    22
    23 class ?DOG? implements ?Cloneable
    24 {
    25 ???? public ?DOG(String?name,? int ?age,?AAA?birthday)
    26 ???? {
    27 ???????? this .name? = ?name;
    28 ???????? this .age? = ?age;
    29 ???????? this .birthday? = ?birthday;
    30 ????}

    31
    32 ???? public ?String?getName()
    33 ???? {
    34 ???????? return ?name;
    35 ????}

    36
    37 ???? public ? int ?getAge()
    38 ???? {
    39 ???????? return ?age;
    40 ????}

    41
    42 ???? public ?AAA?getBirthday()
    43 ???? {
    44 ???????? return ?birthday;
    45 ????}

    46
    47 ???? public ?String?getBirth(AAA?a)
    48 ???? {
    49 ???????? return ?a.name;
    50 ????}

    51
    52 ???? public ?String?name;
    53
    54 ???? private ? int ?age;
    55
    56 ???? public ?AAA?birthday;
    57
    58 ???? public ?Object?clone()
    59 ???? {
    60 ???????? try
    61 ???????? {
    62 ???????????? super .clone();
    63 ???????????? return ? super .clone();
    64 ????????}
    ? catch ?(Exception?e)
    65 ???????? {
    66 ???????????? return ? null ;
    67 ????????}

    68 ????}

    69 }

    70
    71 public ? class ?TestClone
    72 {
    73 ???? public ? static ? void ?main(String[]?args)
    74 ???? {
    75 ????????AAA?Day? = ? new ?AAA( " test " );
    76 ????????DOG?dog1? = ? new ?DOG( " xiaogou " ,? 2 ,?Day);
    77 ????????DOG?dog2? = ?(DOG)?dog1.clone();
    78 ????????dog2.birthday? = ?(AAA)?dog1.birthday.clone(); // 特別注意這里
    79 ????????dog1.birthday.name? = ? " 333 " ;
    80 ????????System.out.println(dog1.getBirth(dog1.birthday));
    81 ????????System.out.println(dog2.getBirth(dog2.birthday));
    82 ????}

    83 }

    84


    運行結果:
    333
    test
    這樣基本就達到了我們當初的母的。


    但是明顯的這種方法還是有許多不足,人們總是希望一個clone就是對象直接克隆。而上面還要對對象中的對象遞歸使用clone。下面提供一種更高級點的做法:

    ?

    ?1 import ?java.io. * ;
    ?2
    ?3 class ?AAA? implements ?Serializable
    ?4 {
    ?5 ???? public ?AAA(String?name)
    ?6 ???? {
    ?7 ???????? this .name? = ?name;
    ?8 ????}

    ?9
    10 ???? public ?String?name;
    11 }

    12
    13 class ?DOG? extends ?SerialCloneable
    14 {
    15 ???? public ?DOG(String?name,? int ?age,?AAA?birthday)
    16 ???? {
    17 ???????? this .name? = ?name;
    18 ???????? this .age? = ?age;
    19 ???????? this .birthday? = ?birthday;
    20 ????}

    21
    22 ???? public ?String?getName()
    23 ???? {
    24 ???????? return ?name;
    25 ????}

    26
    27 ???? public ? int ?getAge()
    28 ???? {
    29 ???????? return ?age;
    30 ????}

    31
    32 ???? public ?AAA?getBirthday()
    33 ???? {
    34 ???????? return ?birthday;
    35 ????}

    36
    37 ???? public ?String?getBirth(AAA?a)
    38 ???? {
    39 ???????? return ?a.name;
    40 ????}

    41
    42 ???? public ?String?name;
    43
    44 ???? private ? int ?age;
    45
    46 ???? public ?AAA?birthday;
    47
    48 ???? public ?Object?clone()
    49 ???? {
    50 ???????? try
    51 ???????? {
    52 ???????????? super .clone();
    53 ???????????? return ? super .clone();
    54 ????????}
    ? catch ?(Exception?e)
    55 ???????? {
    56 ???????????? return ? null ;
    57 ????????}

    58 ????}

    59 }

    60
    61 public ? class ?TestClone
    62 {
    63 ???? public ? static ? void ?main(String[]?args)
    64 ???? {
    65 ????????AAA?Day? = ? new ?AAA( " test " );
    66 ????????DOG?dog1? = ? new ?DOG( " xiaogou " ,? 2 ,?Day);
    67 ????????DOG?dog2? = ?(DOG)?dog1.clone();
    68 ???????? // dog2.birthday?=?(AAA)?dog1.birthday.clone();
    69 ????????dog1.birthday.name? = ? " 333 " ;
    70 ????????System.out.println(dog1.getBirth(dog1.birthday));
    71 ????????System.out.println(dog2.getBirth(dog2.birthday));
    72 ????}

    73 }

    74
    75 class ?SerialCloneable? implements ?Cloneable,?Serializable
    76 {
    77 ???? public ?Object?clone()
    78 ???? {
    79 ???????? try
    80 ???????? {
    81 ????????????ByteArrayOutputStream?bout? = ? new ?ByteArrayOutputStream();
    82 ????????????ObjectOutputStream?out? = ? new ?ObjectOutputStream(bout);
    83 ????????????out.writeObject( this );
    84 ????????????out.close();
    85 ????????????ByteArrayInputStream?bin? = ? new ?ByteArrayInputStream(bout
    86 ????????????????????.toByteArray());
    87 ????????????ObjectInputStream?in? = ? new ?ObjectInputStream(bin);
    88 ????????????Object?ret? = ?in.readObject();
    89 ????????????in.close();
    90 ???????????? return ?ret;
    91 ????????}
    ? catch ?(Exception?e)
    92 ???????? {
    93 ???????????? return ? null ;
    94 ????????}

    95 ????}

    96 }

    97


    輸出:
    333
    test

    上面的代碼用序列化與反序列化實現了對象拷貝。比較通用。但是得注意的是其中的類得implements Serializable。

    ?

    3)后記

    我們如果利用強大的反射機制+序列化與反序列化,能做出更加靈活的對象拷貝。有興趣的朋友可以自行去研究。
    我在javaeye上看到一篇短文:http://www.javaeye.com/post/367014 主要講的就是反射在對象拷貝中的應用。


    ?

    posted on 2008-04-28 11:52 -274°C 閱讀(10463) 評論(6)  編輯  收藏 所屬分類: JAVA


    FeedBack:
    # re: JAVA 對象拷貝
    2008-04-28 12:51 | Jacky-Q
    這代碼縮進真難受....  回復  更多評論
      
    # re: JAVA 對象拷貝
    2008-04-28 14:40 | 々上善若水々
    風中葉的吧。  回復  更多評論
      
    # re: JAVA 對象拷貝
    2008-04-29 10:47 | cc
    super .clone();
    return super .clone();
    這里為什么要寫兩次呢,直接寫
    return super .clone();
    不是更好嗎?  回復  更多評論
      
    # re: JAVA 對象拷貝
    2008-04-29 12:44 | java-he
    @ CC
    同意。  回復  更多評論
      
    # re: JAVA 對象拷貝[未登錄]
    2008-04-30 13:56 | java
    不錯~  回復  更多評論
      
    # re: JAVA 對象拷貝
    2012-07-02 11:25 | j2
    樓主連什么是遞歸都沒有搞清楚,錯別字,錯概念太多了  回復  更多評論
      

    常用鏈接

    留言簿(21)

    隨筆分類(265)

    隨筆檔案(242)

    相冊

    JAVA網站

    關注的Blog

    搜索

    •  

    積分與排名

    • 積分 - 914354
    • 排名 - 40

    最新評論

    主站蜘蛛池模板: 久久久久久av无码免费看大片| 亚洲va在线va天堂成人| 国产区图片区小说区亚洲区| 好男人视频社区精品免费| 亚洲精品自偷自拍无码| 日本特黄特黄刺激大片免费| 麻豆亚洲AV成人无码久久精品 | 精品无码AV无码免费专区| 无码乱人伦一区二区亚洲一| 99久久99热精品免费观看国产| 麻豆亚洲av熟女国产一区二| 91免费国产在线观看| 日本亚洲色大成网站www久久| 成人毛片免费观看| 国产精品亚洲а∨无码播放不卡| 国产精品久久久久影院免费| 免费的黄色的网站| 亚洲成A人片777777| 最近免费中文字幕mv电影| www.亚洲成在线| 免费a级毛片大学生免费观看| 一个人看的www免费在线视频| 国产成人亚洲精品青草天美| 30岁的女人韩剧免费观看| 亚洲精品伦理熟女国产一区二区 | 97碰公开在线观看免费视频| 中文字幕无码精品亚洲资源网久久| 精品国产精品久久一区免费式| 一级一级毛片免费播放| 99久久亚洲综合精品成人网| 最近高清国语中文在线观看免费| 深夜a级毛片免费无码| 亚洲av无码一区二区三区乱子伦| 成人免费视频网站www| 污污视频网站免费观看| 久久噜噜噜久久亚洲va久| 性xxxx视频播放免费| 大地资源中文在线观看免费版| 亚洲不卡中文字幕| 国产亚洲精品看片在线观看 | 91麻豆国产自产在线观看亚洲 |