我的漫漫程序之旅

          專注于JavaWeb開發(fā)
          隨筆 - 39, 文章 - 310, 評論 - 411, 引用 - 0
          數(shù)據(jù)加載中……

          Serializable接口初探

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

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

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

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

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

             defaultReadObject 方法使用流中的信息來分配流中通過當(dāng)前對象中相應(yīng)命名字段保存的對象的字段。這用于處理類發(fā)展后需要添加新字段的情形。該方法本身不需要涉及屬于其超類或子類的狀態(tài)。狀態(tài)是通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數(shù)據(jù)類型的方法將各個字段寫入 ObjectOutputStream 來保存的。看一個列子:   最后結(jié)果如下:
              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 {
                      
          /** *//**//* 創(chuàng)建一個文件寫入序列化樹。 */
                      FileOutputStream ostream 
          = new FileOutputStream(" tree.tmp ");
                      
          /** *//**//* 創(chuàng)建輸出流 */
                      ObjectOutputStream p 
          = new ObjectOutputStream(ostream);

                      
          /** *//**//* 創(chuàng)建一個二層的樹。 */
                      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(
          "   " + name);
                  }
           catch (Exception ex) {
                      ex.printStackTrace();
                  }

              }

          }

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

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

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

          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 々上善若水々 閱讀(1116) 評論(0)  編輯  收藏 所屬分類: J2SE

          主站蜘蛛池模板: 法库县| 延吉市| 托克托县| 沂南县| 麦盖提县| 武定县| 保德县| 防城港市| 安泽县| 长乐市| 澎湖县| 宁陕县| 奉化市| 安化县| 霍邱县| 平南县| 秀山| 沧州市| 喀喇沁旗| 镇远县| 刚察县| 闻喜县| 隆尧县| 亚东县| 千阳县| 长汀县| 平乡县| 古丈县| 清丰县| 阳新县| 漳州市| 阳原县| 邢台市| 定陶县| 吕梁市| 南雄市| 三江| 阿坝县| 苏尼特右旗| 平远县| 马关县|