<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 閱讀(10464) 評論(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

    搜索

    •  

    積分與排名

    • 積分 - 914554
    • 排名 - 40

    最新評論

    主站蜘蛛池模板: 亚洲精品偷拍视频免费观看| 一级做a爰性色毛片免费| 国产亚洲老熟女视频| 黄瓜视频高清在线看免费下载| 中文在线免费视频| 美女的胸又黄又www网站免费| 亚洲欧洲精品在线| 亚洲国产精品无码成人片久久| 免费少妇a级毛片| 麻豆国产入口在线观看免费| 无码国产精品一区二区免费式影视| a毛片在线免费观看| 一个人看的免费观看日本视频www| 亚洲av无一区二区三区| 亚洲最大成人网色香蕉| 亚洲精品视频在线免费| 亚洲激情在线观看| 亚洲妇熟XXXX妇色黄| 亚洲熟妇av一区二区三区| 亚洲国产91精品无码专区| 国产精品免费视频一区| 免费观看一级毛片| 午夜私人影院免费体验区| 国产三级在线观看免费| 性做久久久久久免费观看| 老司机在线免费视频| 国产人在线成免费视频| 一二三四影视在线看片免费| 91视频国产免费| 手机在线免费视频| 日韩成人免费在线| 国产成人免费福利网站| 国产女高清在线看免费观看| 国产一区二区三区免费在线观看| 成人爱做日本视频免费| yy6080亚洲一级理论| 亚洲日韩国产一区二区三区| 亚洲自偷自偷偷色无码中文| 亚洲成AV人片在| 亚洲精品影院久久久久久| 亚洲国产日产无码精品|