隨筆-126  評(píng)論-247  文章-5  trackbacks-0

          題目取得有點(diǎn)怪異,不管這個(gè),其實(shí)是要說(shuō)一下 java 中的 java.io.Serializable 接口。

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

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

              對(duì)象通過(guò)寫出描述自己狀態(tài)的數(shù)值來(lái)記錄自己,這個(gè)過(guò)程就叫對(duì)象的序列化 ( Serialization ) 。

          類可以通過(guò)實(shí)現(xiàn) java.io.Serializable 接口來(lái)啟用其序列化功能。未實(shí)現(xiàn)此接口的類將無(wú)法使其任何狀態(tài)序列化或反序列化。

          類實(shí)現(xiàn) java.io.Serializable 接口,無(wú)需實(shí)現(xiàn)任何方法或字段,因?yàn)?java.io.Serializable 接口本身就沒(méi)有方法或字段,它僅用來(lái)標(biāo)識(shí)可序列化的語(yǔ)義。

          Java 序列化技術(shù)可以讓你將一個(gè)對(duì)象的狀態(tài)寫入到一個(gè) IO 流里,并且可以從其它地方把該 IO 流里的數(shù)據(jù)讀出來(lái)。重新構(gòu)造一個(gè)相同的對(duì)象。

          這就有點(diǎn)像你將數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)里,然后再拿出來(lái),這前后得到的東西是一樣的。它的這種機(jī)制允許你將對(duì)象通過(guò)網(wǎng)絡(luò)進(jìn)行傳播,

          并可以隨時(shí)把對(duì)象持久化到數(shù)據(jù)庫(kù)、文件等系統(tǒng)里。

          另外,序列化運(yùn)行時(shí)使用一個(gè)稱為 serialVersionUID 的版本號(hào)與每個(gè)可序列化類相關(guān)聯(lián),

          該序列號(hào)在反序列化過(guò)程中用于驗(yàn)證序列化對(duì)象的發(fā)送者和接收者是否為該對(duì)象加載了與序列化兼容的類。

          如果接收者加載的該對(duì)象的類的 serialVersionUID 與對(duì)應(yīng)的發(fā)送者的類的版本號(hào)不同,則反序列化將會(huì)導(dǎo)致失敗并拋出 InvalidClassException。

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

          接下來(lái)做個(gè)小示例 :

           
          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 測(cè)試 :

           
          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,后臺(tái)輸出 :

           
          <---- Finished ---->
           

          選中工程名,按 F5 刷新一下,在項(xiàng)目名的根目錄下就生成了一個(gè) user.ser 文件,這就是 User 對(duì)象序列化生成的文件,它記錄了 User 對(duì)象的一些狀態(tài)信息,

          當(dāng)然,你可以根據(jù)需要選擇文件的存放路徑。

          選中 inverseSerializable 方法,右鍵,Run As Junit Test,后臺(tái)輸出 :

           
          ID       : 
          9080
          name :  fancy
           


          1 . 若將 User 類中的序列化接口實(shí)現(xiàn)去掉 :

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

          其余不變,再次運(yùn)行 Junit Test 的 serializable 方法,后臺(tái)拋出異常 :

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


          2 . 先將 User 類撤銷回來(lái) :

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

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

           
          private static final long serialVersionUID = 10086L;
           

          接著,運(yùn)行 Junit Test 的 inverseSerializable 方法,后臺(tái)拋出異常 :

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

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



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

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

          嗯,感謝你的來(lái)訪和評(píng)論,謝謝提醒 ^_^  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 大关县| 浦城县| 宜昌市| 邵武市| 襄汾县| 论坛| 洞头县| 沂源县| 绿春县| 日土县| 讷河市| 红原县| 香河县| 芷江| 东乌珠穆沁旗| 磐安县| 赤城县| 林甸县| 夏河县| 吉首市| 永丰县| 静安区| 泸水县| 鄢陵县| 唐山市| 平塘县| 湘潭市| 阿瓦提县| 江津市| 乌拉特中旗| 阜康市| 墨玉县| 无为县| 平果县| 乌鲁木齐县| 大连市| 海安县| 寿宁县| 顺昌县| 南昌市| 合肥市|