我的漫漫程序之旅

          專注于JavaWeb開發
          隨筆 - 39, 文章 - 310, 評論 - 411, 引用 - 0
          數據加載中……

          Serializable接口初探

          類通過實現 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 來保存的。看一個列子:   最后結果如下:
              node 0
            node 1
          node 2
          node 3
            node 4
          node5
          node 6

          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(
          "   " + name);
                  }
           catch (Exception ex) {
                      ex.printStackTrace();
                  }

              }

          }

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

            在序列化時,有幾點要注意的:
            1:當一個對象被序列化時,只保存對象的非靜態成員變量,不能保存任何的成員方法和靜態的成員變量。
                  2:如果一個對象的成員變量是一個對象,那么這個對象的數據成員也會被保存。
            3:如果一個可序列化的對象包含對某個不可序列化的對象的引用,那么整個序列化操作將會失敗,并且會拋出一個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 "253000.50);
                  Employee e2 
          = new Employee(" lisi "243200.40);
                  Employee e3 
          = new Employee(" wangwu "273800.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);
                  }

              }

          }


          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 ");
              }

          }



          posted on 2007-12-12 08:39 々上善若水々 閱讀(1115) 評論(0)  編輯  收藏 所屬分類: J2SE

          主站蜘蛛池模板: 庆安县| 嘉义县| 疏附县| 高淳县| 怀化市| 阿瓦提县| 湟源县| 应城市| 五家渠市| 南阳市| 武威市| 普陀区| 株洲县| 玉树县| 南宫市| 双江| 新昌县| 翁牛特旗| 泌阳县| 三亚市| 华容县| 寿宁县| 福安市| 故城县| 玉田县| 通渭县| 澄江县| 正宁县| 岳阳县| 汽车| 荔浦县| 建平县| 汶川县| 内丘县| 汤阴县| 宾川县| 怀安县| 郑州市| 博白县| 北海市| 通山县|