JAVA

          人生若只如初見,何事秋風悲畫扇。

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

            類通過實現 java.io.Serializable 接口以啟用其序列化功能。未實現此接口的類將無法使其任何狀態序列化或反序列化??尚蛄谢惖乃凶宇愋捅旧矶际强尚蛄谢?。序列化接口沒有方法或字段,僅用于標識可序列化的語義。

            Java的"對象序列化"能讓你將一個實現了Serializable接口的對象轉換成一組byte,這樣日后要用這個對象時候,你就能把這些byte數據恢復出來,并據此重新構建那個對象了。

            要想序列化對象,你必須先創建一個OutputStream,然后把它嵌進ObjectOutputStream。這時,你就能用writeObject( )方法把對象寫入OutputStream了。

            writeObject 方法負責寫入特定類的對象的狀態,以便相應的 readObject 方法可以還原它。通過調用 out.defaultWriteObject 可以調用保存 Object 的字段的默認機制。該方法本身不需要涉及屬于其超類或子類的狀態。狀態是通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數據類型的方法將各個字段寫入 ObjectOutputStream 來保存的。

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

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

            看一個列子:

          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 ? {?
          ????????????
          /* ?創建一個文件寫入序列化樹。? */ ?
          ????????????FileOutputStream?ostream?
          = ? new ?FileOutputStream( " tree.tmp " );?
          ????????????
          /* ?創建輸出流? */ ?
          ????????????ObjectOutputStream?p?
          = ? new ?ObjectOutputStream(ostream);?

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

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

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

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

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

          ?

            最后結果如下:

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

          LiLy is 惠止南國

            可以看到,在序列化的時候,writeObject與readObject之間的先后順序。readObject將最先write的object read出來。用數據結構的術語來講就姑且稱之為先進先出吧!

            在序列化時,有幾點要注意的:
           ?。保寒斠粋€對象被序列化時,只保存對象的非靜態成員變量,不能保存任何的成員方法和靜態的成員變量。
           ?。玻喝绻粋€對象的成員變量是一個對象,那么這個對象的數據成員也會被保存。
           ?。常喝绻粋€可序列化的對象包含對某個不可序列化的對象的引用,那么整個序列化操作將會失敗,并且會拋出一個NotSerializableException。我們可以將這個引用標記為transient,那么對象仍然可以序列化

            還有我們對某個對象進行序列化時候,往往對整個對象全部序列化了,比如說類里有些數據比較敏感,不希望序列化,一個方法可以用transient來標識,另一個方法我們可以在類里重寫

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

            這二個方法!
            示例:

          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) 評論(5)  編輯  收藏 所屬分類: JEE學習

          評論

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

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

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

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

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

          主站蜘蛛池模板: 西安市| 沂南县| 拉萨市| 克拉玛依市| 台东市| 宁乡县| 深圳市| 永昌县| 泽普县| 民丰县| 贡嘎县| 镇雄县| 增城市| 黄山市| 原平市| 安丘市| 大连市| 商南县| 靖州| 屏山县| 温州市| 石阡县| 讷河市| 青神县| 临漳县| 梁山县| 谢通门县| 漾濞| 七台河市| 新邵县| 正宁县| 科技| 凤台县| 莒南县| 舞钢市| 永泰县| 竹溪县| 顺昌县| 岳西县| 廊坊市| 越西县|