JAVA

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

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

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

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

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

            writeObject 方法負(fù)責(zé)寫入特定類的對(duì)象的狀態(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ī)制,以還原對(duì)象的非靜態(tài)和非瞬態(tài)字段。

             defaultReadObject 方法使用流中的信息來分配流中通過當(dāng)前對(duì)象中相應(yīng)命名字段保存的對(duì)象的字段。這用于處理類發(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?惠止南國(guó) " );
          ????????????p.flush();?
          ????????????ostream.close();????
          // ?關(guān)閉文件。?

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

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

          ????????????new_tree.print(
          2 );?? // ?打印出樹形結(jié)構(gòu)的最上面?2級(jí)?
          ????????????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 惠止南國(guó)

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

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

            還有我們對(duì)某個(gè)對(duì)象進(jìn)行序列化時(shí)候,往往對(duì)整個(gè)對(duì)象全部序列化了,比如說類里有些數(shù)據(jù)比較敏感,不希望序列化,一個(gè)方法可以用transient來標(biāo)識(shí),另一個(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 閱讀(4511) 評(píng)論(5)  編輯  收藏 所屬分類: JEE學(xué)習(xí)

          評(píng)論

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

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

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

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

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

          主站蜘蛛池模板: 岳西县| 尖扎县| 西藏| 北川| 双峰县| 蒲城县| 通榆县| 静乐县| 芜湖县| 青冈县| 滨海县| 页游| 柞水县| 邹平县| 桐庐县| 定边县| 莆田市| 彭阳县| 黑龙江省| 辽中县| 钟祥市| 康定县| 舟曲县| 邵武市| 汕头市| 天全县| 徐闻县| 剑阁县| 南雄市| 恩平市| 蓬安县| 红原县| 邵东县| 商城县| 凤阳县| 抚松县| 玉龙| 武鸣县| 兴安盟| 苗栗市| 贵港市|