posts - 108,comments - 56,trackbacks - 0
              經(jīng)常看到有些類調(diào)用了Serializable接口,而有些類又沒有調(diào)用Serializable接口。那么什么情況下要調(diào)用Serializable接口。

              首先來了解一下Serializable。(類通過實現(xiàn) java.io.Serializable 接口以啟用其序列化功能。未實現(xiàn)此接口的類將無法使其任何狀態(tài)序列化或反序列化。序列化接口Serializable沒有方法或字段,僅用于標識可序列化的語義)


              實現(xiàn)了Serializable接口的對象,可將它們轉(zhuǎn)換成一系列字節(jié),并可在以后完全恢復回原來的樣子。這一過程亦可通過網(wǎng)絡進行。這意味著序列化機制能自動補償操作系統(tǒng)間的差異。換句話說,可以先在Windows機器上創(chuàng)建一個對象,對其序列化,然后通過網(wǎng)絡發(fā)給一臺Unix機器,然后在那里準確無誤地重新“裝配”。不必關心數(shù)據(jù)在不同機器上如何表示,也不必關心字節(jié)的順序或者其他任何細節(jié)。


              serialization主要用來支持2種主要的特性:
              1、RMI(Remote method invocation)。RMI允許象在本機上一樣操作遠程機器上的對象。當發(fā)送消息給遠程對象和調(diào)用遠程方法時,就需要用到serializaiton機制來發(fā)送參數(shù)和接收返回值。
              2、保存信息。在某個時候把狀態(tài)信息保存起來,以便以后某個時候能恢復這些狀態(tài)信息。
              Hibernaet和EJB中的實體Bean就用到了上面兩個特性。


              另外:保存的時候不僅能保存對象的副本,而且還會把對象里面所引用的對象也保存起來,以此類推。就像在編譯某個類一樣,會涉及到所用到的所有類。但是所引用的對象也必須是可序列化的,不然會拋NotSerializableException異常。

              
              下面來寫個例子:(A和B類都是可序列化的,WriteObj:將A序列化,ReadObj:將A反序列化) 
          class A

          class B

          class WriteSeri

          class ReadSeri
              首先,我們運行WriteObj,實現(xiàn)序列化,得到輸出結(jié)果
          write obj :a.toString <a.name="my name is a" a.b.name="my name is B">
          a
          =woxingwosu.A@a90653 b=woxingwosu.B@de6ced
              然后我們再運行ReadObj,實現(xiàn)反序列化,得到輸出結(jié)果
          read Object :a.toString <a.name="my name is a" a.b.name="my name is B">
          a
          =woxingwosu.A@a90653 b=woxingwosu.B@de6ced


              遺漏了一個問題,就是標識版本的serialVersionUID。
              官方文檔:如果可序列化類未顯式聲明 serialVersionUID,則序列化運行時將基于該類的各個方面計算該類的默認 serialVersionUID 值,如“Java(TM) 對象序列化規(guī)范”中所述。不過,強烈建議 所有可序列化類都顯式聲明 serialVersionUID 值,原因計算默認的 serialVersionUID 對類的詳細信息具有較高的敏感性,根據(jù)編譯器實現(xiàn)的不同可能千差萬別,這樣在反序列化過程中可能會導致意外的 InvalidClassException。因此,為保證 serialVersionUID 值跨不同 java 編譯器實現(xiàn)的一致性,序列化類必須聲明一個明確的 serialVersionUID 值。還強烈建議使用 private 修改器顯示聲明 serialVersionUID(如果可能),原因是這種聲明僅應用于立即聲明類 -- serialVersionUID 字段作為繼承成員沒有用處。

              剛才寫的例子中就沒有用到serialVersionUID,這時JVM會根據(jù)類名、接口名、成員方法及屬性等來生成一個64位的哈希字段作為serialVersionUID。但是如果序列化和反序列化的JVM版本不一樣的話,還是顯示寫上serialVersionUID安全。

              以上是個人看法,如有錯誤之處,還望指出。
          posted on 2007-07-12 11:06 破繭而出 閱讀(7549) 評論(3)  編輯  收藏 所屬分類: Java

          FeedBack:
          # re: 為什么使用Serializable(序列化)
          2007-07-12 11:50 | BeanSoft
          不錯, 謝謝分享!  回復  更多評論
            
          # re: 為什么使用Serializable(序列化)
          2009-01-13 10:44 | xx
          為何Serializable沒有屬性,沒有方法?這樣也行?  回復  更多評論
            
          # re: 為什么使用Serializable(序列化)
          2009-12-17 11:06 | Tee
          很好!  回復  更多評論
            
          主站蜘蛛池模板: 翁牛特旗| 祁阳县| 浏阳市| 铜鼓县| 新化县| 赣榆县| 会东县| 深水埗区| 永昌县| 五莲县| 托里县| 宜城市| 和田市| 五大连池市| 潞西市| 乌兰县| 高尔夫| 长海县| 丹阳市| 灯塔市| 祁连县| 尼玛县| 临清市| 裕民县| 大余县| 陵川县| 玉溪市| 晋江市| 天气| 年辖:市辖区| 资中县| 衡水市| 沅江市| 北川| 东乡县| 涟源市| 临颍县| 江口县| 赤水市| 成都市| 鲁甸县|