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

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

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

    JAVA

    人生若只如初見,何事秋風(fēng)悲畫扇。

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      50 隨筆 :: 25 文章 :: 157 評論 :: 0 Trackbacks

      類通過實(shí)現(xiàn) java.io.Serializable 接口以啟用其序列化功能。未實(shí)現(xiàn)此接口的類將無法使其任何狀態(tài)序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。序列化接口沒有方法或字段,僅用于標(biāo)識可序列化的語義。

      Java的"對象序列化"能讓你將一個(gè)實(shí)現(xiàn)了Serializable接口的對象轉(zhuǎn)換成一組byte,這樣日后要用這個(gè)對象時(shí)候,你就能把這些byte數(shù)據(jù)恢復(fù)出來,并據(jù)此重新構(gòu)建那個(gè)對象了。

      要想序列化對象,你必須先創(chuàng)建一個(gè)OutputStream,然后把它嵌進(jìn)ObjectOutputStream。這時(shí),你就能用writeObject( )方法把對象寫入OutputStream了。

      writeObject 方法負(fù)責(zé)寫入特定類的對象的狀態(tài),以便相應(yīng)的 readObject 方法可以還原它。通過調(diào)用 out.defaultWriteObject 可以調(diào)用保存 Object 的字段的默認(rèn)機(jī)制。該方法本身不需要涉及屬于其超類或子類的狀態(tài)。狀態(tài)是通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數(shù)據(jù)類型的方法將各個(gè)字段寫入 ObjectOutputStream 來保存的。

      讀的時(shí)候,你得把InputStream嵌到ObjectInputStream里面,然后再調(diào)用readObject( )方法。不過這樣讀出來的,只是一個(gè)Object的reference,因此在用之前,還得先下傳。readObject 方法負(fù)責(zé)從流中讀取并還原類字段。它可以調(diào)用 in.defaultReadObject 來調(diào)用默認(rèn)機(jī)制,以還原對象的非靜態(tài)和非瞬態(tài)字段。

       defaultReadObject 方法使用流中的信息來分配流中通過當(dāng)前對象中相應(yīng)命名字段保存的對象的字段。這用于處理類發(fā)展后需要添加新字段的情形。該方法本身不需要涉及屬于其超類或子類的狀態(tài)。狀態(tài)是通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數(shù)據(jù)類型的方法將各個(gè)字段寫入 ObjectOutputStream 來保存的。

      看一個(gè)列子:

    import ?java.io. * ;?

    class ?tree? implements ?java.io.Serializable? {?
    ????
    public ?tree?left;?
    ????
    public ?tree?right;?
    ????
    public ? int ?id;?
    ????
    public ? int ?level;?

    ????
    private ? static ? int ?count? = ? 0 ;?

    ????
    public ?tree( int ?depth)? {?
    ????????id?
    = ?count ++ ;?
    ????????level?
    = ?depth;?
    ????????
    if ?(depth? > ? 0 )? {?
    ????????????left?
    = ? new ?tree(depth - 1 );?
    ????????????right?
    = ? new ?tree(depth - 1 );?
    ????????}
    ?
    ????}
    ?

    ????
    public ? void ?print( int ?levels)? {?
    ????????
    for ?( int ?i? = ? 0 ;?i? < ?level;?i ++ )?
    ????????????System.out.print(
    " ?? " );?
    ????????System.out.println(
    " node? " ? + ?id);?

    ????????
    if ?(level? <= ?levels? && ?left? != ? null )?
    ????????????left.print(levels);?

    ????????
    if ?(level? <= ?levels? && ?right? != ? null )?
    ????????????right.print(levels);?
    ????}
    ?


    ????
    public ? static ? void ?main?(String?argv[])? {?

    ????????
    try ? {?
    ????????????
    /* ?創(chuàng)建一個(gè)文件寫入序列化樹。? */ ?
    ????????????FileOutputStream?ostream?
    = ? new ?FileOutputStream( " tree.tmp " );?
    ????????????
    /* ?創(chuàng)建輸出流? */ ?
    ????????????ObjectOutputStream?p?
    = ? new ?ObjectOutputStream(ostream);?

    ????????????
    /* ?創(chuàng)建一個(gè)二層的樹。? */ ?
    ????????????tree?base?
    = ? new ?tree( 2 );?

    ????????????p.writeObject(base);?
    // ?將樹寫入流中。?
    ????????????p.writeObject( " LiLy?is?惠止南國 " );
    ????????????p.flush();?
    ????????????ostream.close();????
    // ?關(guān)閉文件。?

    ????????????
    /* ?打開文件并設(shè)置成從中讀取對象。? */ ?
    ????????????FileInputStream?istream?
    = ? new ?FileInputStream( " tree.tmp " );?
    ????????????ObjectInputStream?q?
    = ? new ?ObjectInputStream(istream);?

    ????????????
    /* ?讀取樹對象,以及所有子樹? */ ?
    ????????????tree?new_tree?
    = ?(tree)q.readObject();?

    ????????????new_tree.print(
    2 );?? // ?打印出樹形結(jié)構(gòu)的最上面?2級?
    ????????????String?name? = ?(String)q.readObject();
    ????????????System.out.println(
    " \n " + name);
    ????????}
    ? catch ?(Exception?ex)? {?
    ????????????ex.printStackTrace();?
    ????????}
    ?
    ????}
    ?
    }
    ?

    ?

      最后結(jié)果如下:

    ??? node 0
    ? node 1
    node 2
    node 3
    ? node 4
    node 5
    node 6

    LiLy is 惠止南國

      可以看到,在序列化的時(shí)候,writeObject與readObject之間的先后順序。readObject將最先write的object read出來。用數(shù)據(jù)結(jié)構(gòu)的術(shù)語來講就姑且稱之為先進(jìn)先出吧!

      在序列化時(shí),有幾點(diǎn)要注意的:
      1:當(dāng)一個(gè)對象被序列化時(shí),只保存對象的非靜態(tài)成員變量,不能保存任何的成員方法和靜態(tài)的成員變量。
      2:如果一個(gè)對象的成員變量是一個(gè)對象,那么這個(gè)對象的數(shù)據(jù)成員也會被保存。
      3:如果一個(gè)可序列化的對象包含對某個(gè)不可序列化的對象的引用,那么整個(gè)序列化操作將會失敗,并且會拋出一個(gè)NotSerializableException。我們可以將這個(gè)引用標(biāo)記為transient,那么對象仍然可以序列化

      還有我們對某個(gè)對象進(jìn)行序列化時(shí)候,往往對整個(gè)對象全部序列化了,比如說類里有些數(shù)據(jù)比較敏感,不希望序列化,一個(gè)方法可以用transient來標(biāo)識,另一個(gè)方法我們可以在類里重寫

    private ? void ?readObject(java.io.ObjectInputStream?stream)
    ?????
    throws
    ?IOException,?ClassNotFoundException;
    ?
    private ? void
    ?writeObject(java.io.ObjectOutputStream?stream)
    ?????
    throws
    ?IOException

      這二個(gè)方法!
      示例:

    import ?java.io. * ;

    class ?ObjectSerialTest
    {
    ????
    public ? static ? void ?main(String[]?args)? throws ?Exception
    ????
    {
    ????????Employee?e1
    = new ?Employee( " zhangsan " , 25 , 3000.50 );
    ????????Employee?e2
    = new ?Employee( " lisi " , 24 , 3200.40 );
    ????????Employee?e3
    = new ?Employee( " wangwu " , 27 , 3800.55 );
    ????????
    ????????FileOutputStream?fos
    = new ?FileOutputStream( " employee.txt " );
    ????????ObjectOutputStream?oos
    = new ?ObjectOutputStream(fos);
    ????????oos.writeObject(e1);
    ????????oos.writeObject(e2);
    ????????oos.writeObject(e3);
    ????????oos.close();
    ????????
    ????????FileInputStream?fis
    = new ?FileInputStream( " employee.txt " );
    ????????ObjectInputStream?ois
    = new ?ObjectInputStream(fis);
    ????????Employee?e;
    ????????
    for ( int ?i = 0 ;i < 3 ;i ++ )
    ????????
    {
    ????????????e
    = (Employee)ois.readObject();
    ????????????System.out.println(e.name
    + " : " + e.age + " : " + e.salary);
    ????????}

    ????????ois.close();
    ????}

    }


    class ?Employee? implements ?Serializable
    {
    ????String?name;
    ????
    int ?age;
    ????
    double ?salary;
    ????
    transient ?Thread?t = new ?Thread();
    ????
    public ?Employee(String?name, int ?age, double ?salary)
    ????
    {
    ????????
    this .name = name;
    ????????
    this .age = age;
    ????????
    this .salary = salary;
    ????}

    ????
    private ? void ?writeObject(java.io.ObjectOutputStream?oos)? throws ?IOException
    ????
    {
    ????????oos.writeInt(age);
    ????????oos.writeUTF(name);
    ????????System.out.println(
    " Write?Object " );
    ????}

    ????
    private ? void ?readObject(java.io.ObjectInputStream?ois)? throws ?IOException
    ????
    {
    ????????age
    = ois.readInt();
    ????????name
    = ois.readUTF();
    ????????System.out.println(
    " Read?Object " );
    ????}


    }

      --(add on 2006/6/28)
    ?

    參考資料:JDK1.5 API DOC  孫鑫老師資料

    posted on 2006-05-10 12:47 Jkallen 閱讀(4508) 評論(5)  編輯  收藏 所屬分類: JEE學(xué)習(xí)

    評論

    # re: 初探序列化---Serializable 2006-08-25 10:21 le
    講的不錯(cuò),很清楚.  回復(fù)  更多評論
      

    # re: 初探序列化---Serializable 2006-10-14 18:06 Sol
    不錯(cuò),頂  回復(fù)  更多評論
      

    # re: 初探序列化---Serializable 2007-04-28 18:31 吼吼
    自己比著例子做的,才發(fā)現(xiàn)是怎么回事  回復(fù)  更多評論
      

    # re: 初探序列化---Serializable[未登錄] 2007-07-26 14:10 binbin
    謝謝....  回復(fù)  更多評論
      

    # re: 初探序列化---Serializable 2007-08-21 18:03 555
    555!  回復(fù)  更多評論
      

    主站蜘蛛池模板: 免费夜色污私人影院网站电影| 免费观看激色视频网站bd| 国产午夜亚洲不卡| 91精品全国免费观看含羞草| 亚洲综合激情五月丁香六月| 国产成人综合亚洲AV第一页 | 在线a级毛片免费视频| 免费人成网站永久| 亚洲精品永久www忘忧草| 国产乱子影视频上线免费观看| 成人无码a级毛片免费| 亚洲色少妇熟女11p| 国产亚洲精品一品区99热| 永久黄网站色视频免费观看| 人妻在线日韩免费视频| 亚洲AV无码片一区二区三区| 亚洲成AV人片在线播放无码| 午夜男人一级毛片免费| 永久免费AV无码网站国产| 亚洲a∨无码一区二区| 亚洲精品午夜在线观看| 国产综合亚洲专区在线| 免费毛片在线播放| 一区二区三区四区免费视频 | 免费av欧美国产在钱| 在线看片免费人成视频久网下载| 亚洲欧美国产国产综合一区| 亚洲国产精品久久久久婷婷软件| 亚洲国产精品人人做人人爱| 男女超爽刺激视频免费播放 | 羞羞视频免费网站在线看| 亚洲欧美国产国产一区二区三区 | 亚洲日韩在线视频| 亚洲国产精品成人精品无码区在线| 国产在线观看免费完整版中文版 | 18禁成人网站免费观看 | 免费国产一级特黄久久| 无码国产精品久久一区免费| 无码国产精品一区二区免费vr| 久久免费99精品国产自在现线| 亚洲av片在线观看|