Flyingis

          Talking and thinking freely !
          Flying in the world of GIS !
          隨筆 - 156, 文章 - 16, 評論 - 589, 引用 - 0
          數(shù)據(jù)加載中……

          Java I/O中的對象序列化

          作者:Flyingis

                Java對象序列化將那些實現(xiàn)了Serializable接口的對象轉(zhuǎn)換成一個字節(jié)序列,并能夠以后將這個字節(jié)序列完全恢復為原來的對象。利用對象的序列化,可以實現(xiàn)輕量級持久性,這意味著一個對象的生存周期并不取決于程序是否正在執(zhí)行,它可以生存于程序的調(diào)用之間。通過將一個序列化對象寫入磁盤,然后在重新調(diào)用程序時恢復該對象,就能夠?qū)崿F(xiàn)持久性的效果。JDOHibernate等中間件為我們提供了更規(guī)范、完善的持久化機制,這里所述只是最基本的基于文件I/O的持久化。

          對象序列化主要是為了支持兩種主要的特性,一是Java遠程方法調(diào)用(RMI),另外一個是序列化Java Beans

          1.        實現(xiàn)了Serializable接口的對象的序列化

          要序列化一個對象,首先要創(chuàng)建OutputStream對象,然后將其封裝在一個ObjectOutputStream對象內(nèi)。此時,調(diào)用writeObject()方法將對象序列化并發(fā)送給OutputStream。在反序列化時,需要將一個InputStream封裝在ObjectInputStream內(nèi),然后調(diào)用readObject(),得到的結(jié)果是一個Object對象,需要進行轉(zhuǎn)型得到最后所需的對象。需要注意的是,在對一個Serializable對象進行反序列化的過程中,沒有調(diào)用任何構(gòu)造器,包括缺省的構(gòu)造器,整個對象都是通過從InputStream中取得數(shù)據(jù)恢復過來的。對象序列化是面向字節(jié)的,因此采用InputStreamOutputStream層次結(jié)構(gòu)。

          2.        實現(xiàn)了Externalizable接口的對象的序列化

          Externalizable接口繼承了Serializable接口,同時添加了writeExternal()readExternal(),它們在序列化和反序列化過程中會被自動調(diào)用。出于安全的考慮,可以將需要序列化的對象在上述方法中顯式處理,否則不用在上述兩個方法內(nèi)考慮。注意,對于實現(xiàn)了Serializable接口的對象,對象完全以它存儲的二進制位為基礎(chǔ)來構(gòu)造,不調(diào)用構(gòu)造器。而對于一個Externalizable對象,所有普通的缺省構(gòu)造器都會被調(diào)用,然后調(diào)用readExternal()

          3.        transient關(guān)鍵字

          在某些情況下,有些特定的子對象不希望Java序列化機制自動保存與恢復,即使對象中的這些信息是private的,經(jīng)過序列化處理,就可以通過讀取文件或者攔截網(wǎng)絡(luò)傳輸?shù)姆绞絹碓L問到它。實現(xiàn)了Externalizable接口的對象的writeExternal()方法可以對需要的對象進行顯式的序列化,但是如果我們操作的是一個實現(xiàn)了Serializable接口的對象,就只能用transient關(guān)鍵字逐個字段的關(guān)閉序列化,只需要在字段定義前加上該關(guān)鍵字即可。

          4.        實現(xiàn)了Serializable接口的同時,提供兩個方法

          private void writeObject(ObjectOutputStream stream) throws IOException

          private void readObject(ObjectInputStream stream)

          throws IOException, ClassNotFoundException

          這種方法使用起來比較混亂,僅僅提供了這樣的一種功能,絕大多數(shù)情況下,使用前面三種方法就能滿足需求。

          posted on 2006-01-08 13:13 Flyingis 閱讀(2630) 評論(5)  編輯  收藏 所屬分類: JavaSE

          評論

          # re: Java I/O中的對象序列化  回復  更多評論   

          第四種Serializable才是提倡的做法。建議讀讀Effective Java中關(guān)于Serializable那章
          2006-01-12 10:26 | riverbuilding

          # re: Java I/O中的對象序列化  回復  更多評論   

          第四種理解起來有些晦澀,有時間我會進行考證。
          2006-01-12 10:40 | Flyingis

          # re: Java I/O中的對象序列化  回復  更多評論   

          >在對一個Serializable對象進行反序列化的過程中,沒有調(diào)用任何構(gòu)造器,包括缺省的構(gòu)造器

          抱歉又要挑刺了,Serializable對象在反序列化時,是要調(diào)用缺省構(gòu)造函數(shù)的,否則 JVM 怎么知道多了一個對象實例?
          2006-01-13 13:53 | 笨笨

          # re: Java I/O中的對象序列化  回復  更多評論   

          @ 笨笨
          每一次復習都會帶來許多新的體會,也會存在知識的盲點,本來就是學習,歡迎你隨時挑刺。
          關(guān)于Serializable對象進行反序列化的過程中是否調(diào)用構(gòu)造器,我在網(wǎng)上搜索了一下,沒找到確切的答案。這句話源自《Thinking in Java 3rd》。
          2006-01-14 12:45 | Flyingis

          # re: Java I/O中的對象序列化  回復  更多評論   

          沒有最后一種的話,以前java不能實現(xiàn)真正的singleton pattern的。
          最后一種很有用。
          2006-01-22 13:50 | 程序員
          主站蜘蛛池模板: 张北县| 抚顺市| 大名县| 册亨县| 泗洪县| 灵川县| 遂宁市| 泸西县| 黄平县| 英德市| 永州市| 盐边县| 西丰县| 荔波县| 神农架林区| 临洮县| 上高县| 黄龙县| 沈阳市| 聂荣县| 平谷区| 平邑县| 宁乡县| 马边| 乐清市| 江永县| 双流县| 子长县| 衡水市| 霞浦县| 南昌县| 池州市| 海伦市| 锡林郭勒盟| 苏州市| 富川| 萨嘎县| 荣昌县| 淮南市| 莱西市| 武清区|