程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> J2SE中的序列化之接受默認序列化

J2SE中的序列化之接受默認序列化

編輯:JAVA編程入門知識

  首先要了解Java默認的序列化行為,java將一切關於對象的信息都保存了下了,也就是說,有些時候那些不需要保存的也被保存了下來。一般情況下,我們僅僅需要保存邏輯數據就可以了。不需要保存的數據我們可以用要害字transient標出。
  
  以下是一個例子:
  
   import java.io.*;
  
  public class Serial implements Serializable {
  
   int company_id;
  
   String company_addr;
  
   transient boolean company_flag;
  
  }
  
  則company_flag字段將不會參與序列化與反序列化,但同時你也增加了為他初始值的責任。這也是序列化經常導致的問題之一。因為序列化相當於一個只接受數據流的public構造函數,這種對象構造方法是語言之外的。但他仍然是一種形式上的構造函數。如若你的類不能夠通過其他方面來保證初始化,則你需要額外的提供readObject方法,首先正常的反序列化,然後對transient標示的字段進行初始化。
  
  在不適合的時候,使用java默認的序列化行為可能會帶來速度上的影響,最糟糕的情況是,可能導致溢出。在某些數據結構的實現中,經常會充斥著各種的循環引用,而java的默認序列化行為,並不了解你的對象結構,其結果就是java試圖通過一種昂貴的“圖遍歷”來保存對象狀態。可想而知,不但慢而且可能溢出。這時候你就要提供自己的readObject,來代替默認的行為。
  
  兼容性問題
  
  兼容性歷來是復雜而麻煩的問題。
  
  不要兼容性:
  
  首先來看看假如我們的目的是不要兼容性,應該注重哪些。不要兼容性的場合很多,比如war3每當版本升級就不能夠讀取以前的replays。
  
  兼容也就是版本控制,java通過一個名為UID(stream unique identifier)來控制,這個UID是隱式的,它通過類名,方法名等諸多因素經過計算而得,理論上是一一映射的關系,也就是唯一的。假如UID不一樣的話,就無法實現反序列化了,並且將會得到InvalidClassException。
  
  當我們要人為的產生一個新的版本(實現並沒有改動),而拋棄以前的版本的話,可以通過顯式的聲名UID來實現:
  
   private static final long serialVersionUID=****; 你可以編造一個版本號,但注重不要重復。這樣在反序列化的時候老版本將得到InvalidClassException,我們可以在老版本的地方捕捉這個異常,並提示用戶升級的新的版本。
  
  當改動不大時,保持兼容性(向下兼容性的一個特例):
  
  有時候你的類增加了一些無關緊要的非私有方法,而邏輯字段並不改變的時候,你當然希望老版本和新版本保持兼容性,方法同樣是通過顯式的聲名UID來實現。下面我們驗證一下。
  
  老版本:
  
   import java.io.*;
  
  public class Serial implements Serializable {
  
   int company_id;
  
   String company_addr;
  
   public Serial1(int company_id, String company_addr) {
  
  this.company_id = company_id;
  
  this.company_addr = company_addr;
  
   }
  
   public String toString() {
  
  return "DATA: "+company_id+" "+
  
  company_addr;
  
   }
  
  }新版本
  
   import java.io.*;
  
  public class Serial implements Serializable {
  
   int company_id;
  
   String company_addr;
  
   public Serial1(int company_id, String company_addr) {
  
  this.company_id = company_id;
  
  this.company_addr = company_addr;
  
   }
  
   public String toString() {
  
  return "DATA: "+company_id+" "+ company_addr;
  
   }
  
   public void todo(){}//無關緊要的方法
  
  } 首先將老版本序列化,然後用新版本讀出,發生錯誤:
  
   java.io.InvalidClassException: Serial.Serial1; local class incompatible: stream classdesc serialVersionUID = 762508508425139227, local class serialVersionUID = 1187169935661445676 接下來我們加入顯式的聲名UID:
  
   private static final long serialVersionUID=762508508425139227l; 再次運行,順利地產生新對象
  
  DATA: 1001 com1
  
  如何保持向上兼容性:
  
  向上兼容性是指老的版本能夠讀取新的版本序列化的數據流。經常出現在我們的服務器的數據更新了,仍然希望老的客戶端能夠支持反序列化新的數據流,直到其更新到新的版本。可以說,這是半自動的事情。
  
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved