隨筆-126  評論-247  文章-5  trackbacks-0

          題目取得有點怪異,不管這個,其實是要說一下 java 中的 java.io.Serializable 接口。

          首先,先來了解一下什么是 序列化  ( Serializable ) : 
           
              對象的壽命通常隨著生成該對象的程序塊的終止而終止。有時候,你可能需要將對象的狀態保存下來,在需要時再將對象恢復(反序列化)。

              我們把對象的這種能記錄自己的狀態以便將來再生的能力,叫做對象的持久性 ( persistence )。

              對象通過寫出描述自己狀態的數值來記錄自己,這個過程就叫對象的序列化 ( Serialization ) 。

          類可以通過實現 java.io.Serializable 接口來啟用其序列化功能。未實現此接口的類將無法使其任何狀態序列化或反序列化。

          類實現 java.io.Serializable 接口,無需實現任何方法或字段,因為 java.io.Serializable 接口本身就沒有方法或字段,它僅用來標識可序列化的語義。

          Java 序列化技術可以讓你將一個對象的狀態寫入到一個 IO 流里,并且可以從其它地方把該 IO 流里的數據讀出來。重新構造一個相同的對象。

          這就有點像你將數據存儲到數據庫里,然后再拿出來,這前后得到的東西是一樣的。它的這種機制允許你將對象通過網絡進行傳播,

          并可以隨時把對象持久化到數據庫、文件等系統里。

          另外,序列化運行時使用一個稱為 serialVersionUID 的版本號與每個可序列化類相關聯,

          該序列號在反序列化過程中用于驗證序列化對象的發送者和接收者是否為該對象加載了與序列化兼容的類。

          如果接收者加載的該對象的類的 serialVersionUID 與對應的發送者的類的版本號不同,則反序列化將會導致失敗并拋出 InvalidClassException。

          如還想要更進一步的詳細信息,可以自行查看 JDK 的 API,里面對 Serializable 做了比較詳細的解釋。

          接下來做個小示例 :

           
          package net.yeah.fancydeepin.model;

          import java.io.Serializable;

          public class User implements Serializable{

              
          private static final long serialVersionUID = 1L;
              
              
          private Integer  id;
              
          private String     name;
              
              
          public User(){
                  
              }
              
              
          public User (Integer id, String name){
                  
          this.id   = id;
                  
          this.name = name;
              }
              
              
          public Integer getId() {
                  
          return id;
              }
              
              
          public String getName() {
                  
          return name;
              }
              
              
          public void setId(Integer id) {
                  
          this.id = id;
              }
              
              
          public void setName(String name) {
                  
          this.name = name;
              }
              
          }
           


          Junit 測試 :

           
          package junit.test;

          import org.junit.Test;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.ObjectInputStream;
          import java.io.ObjectOutputStream;
          import net.yeah.fancydeepin.model.User;

          public class TestApp {

              @Test
              
          public void serializable() throws Exception{
                  
                  User user 
          = new User(9080"fancy");
                  ObjectOutputStream outStream 
          = new ObjectOutputStream(new FileOutputStream("user.ser"));
                  outStream.writeObject(user);
                  System.out.println(
          "<---- Finished ---->");
              }
              
              @Test
              
          public void inverseSerializable() throws Exception{
                  
                  ObjectInputStream inputStream 
          = new ObjectInputStream(new FileInputStream("user.ser"));
                  User user 
          = (User)inputStream.readObject();
                  System.out.println(
          "ID   : " + user.getId());
                  System.out.println(
          "name : " + user.getName());
              }
              
          }
           

          選中 serializable 方法,右鍵,Run As Junit Test,后臺輸出 :

           
          <---- Finished ---->
           

          選中工程名,按 F5 刷新一下,在項目名的根目錄下就生成了一個 user.ser 文件,這就是 User 對象序列化生成的文件,它記錄了 User 對象的一些狀態信息,

          當然,你可以根據需要選擇文件的存放路徑。

          選中 inverseSerializable 方法,右鍵,Run As Junit Test,后臺輸出 :

           
          ID       : 
          9080
          name :  fancy
           


          1 . 若將 User 類中的序列化接口實現去掉 :

           
          package net.yeah.fancydeepin.model;

          public class User{
              
              
          private Integer id;
              
          private String  name;
              
              
          public User(){
                  
              }
              
              
          public User (Integer id, String name){
                  
          this.id   = id;
                  
          this.name = name;
              }
              
              
          public Integer getId() {
                  
          return id;
              }
              
              
          public String getName() {
                  
          return name;
              }
              
              
          public void setId(Integer id) {
                  
          this.id = id;
              }
              
              
          public void setName(String name) {
                  
          this.name = name;
              }
              
          }
           

          其余不變,再次運行 Junit Test 的 serializable 方法,后臺拋出異常 :

           
          java.io.NotSerializableException: net.yeah.fancydeepin.model.User
           


          2 . 先將 User 類撤銷回來 :

           
          package net.yeah.fancydeepin.model;

          import java.io.Serializable;

          public class User implements Serializable{

              
          private static final long serialVersionUID = 1L;
              
              
          private Integer id;
              
          private String  name;
              
              
          public User(){
                  
              }
              
              
          public User (Integer id, String name){
                  
          this.id   = id;
                  
          this.name = name;
              }
              
              
          public Integer getId() {
                  
          return id;
              }
              
              
          public String getName() {
                  
          return name;
              }
              
              
          public void setId(Integer id) {
                  
          this.id = id;
              }
              
              
          public void setName(String name) {
                  
          this.name = name;
              }
              
          }
           

          其余不變,再次運行 Junit Test 的 serializable 方法,先讓它正確序列化 User 對象生成 user.ser,接著,修改 serialVersionUID 的值 :

           
          private static final long serialVersionUID = 10086L;
           

          接著,運行 Junit Test 的 inverseSerializable 方法,后臺拋出異常 :

           
          java.io.InvalidClassException: net.yeah.fancydeepin.model.User; local 
          class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 10086
           

          這兩個異常是為了幫助朋友們理解 Serializable,異常信息都比較容易理解和接受,這里就不多解釋了,本文也到此結束。



            
          posted on 2012-10-05 18:38 fancydeepin 閱讀(3241) 評論(3)  編輯  收藏

          評論:
          # re: implements java.io.Serializable 2012-10-08 08:32 | dohkoos
          序列化 Serializable
          反序列化 Deserialize  回復  更多評論
            
          # re: implements java.io.Serializable 2012-10-08 08:35 | dohkoos
          序列化 Serialize
          反序列化 Deserialize  回復  更多評論
            
          # re: implements java.io.Serializable 2012-10-11 15:22 | fancydeepin
          回復 @dohkoos

          嗯,感謝你的來訪和評論,謝謝提醒 ^_^  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 满城县| 隆昌县| 安塞县| 铜陵市| 新源县| 建德市| 铁岭市| 砀山县| 襄城县| 秭归县| 麻城市| 泗水县| 寻乌县| 尤溪县| 林西县| 靖远县| 叶城县| 屏边| 黔西县| 奉化市| 阿克陶县| 靖远县| 苍梧县| 昌图县| 札达县| 伊春市| 泸水县| 木兰县| 黎平县| 普兰店市| 昂仁县| 上虞市| 烟台市| 城口县| 达日县| 镇安县| 富蕴县| 塘沽区| 玉田县| 隆化县| 漳平市|