條理性解讀JAVA對象序列化的用途

1、什麼是JAVA對象序列化?java

序列化分爲兩大部分:序列化和反序列化。安全

java對象序列化就是將對象的狀態轉換成字節流,之後能夠經過這些值再生成相同狀態的對象!以便存儲在文件中或在網絡上傳輸。對象序列化是對象持久化的一種實現方法,它是將一個對象的屬性和方法轉化爲一種序列化的格式以用於存儲和傳輸;網絡

反序列化就是根]打開字節流並重構對象的過程。socket

 

2、JAVA對象序列化機制有什麼用?分佈式

通常來說有兩種用途:學習

Java的JavaBeans:Bean的狀態信息一般是在設計時配置的,Bean的狀態信息必須被存起來,以便當程序運行時能恢復這些狀態信息,這須要將對象的狀態保存到文件中,然後可以經過讀入對象狀態來從新構造對象,恢復程序狀態。加密

對象序列化能夠實現分佈式對象。主要應用例如:RMI(JavaRMI指的是遠程方法調用(RemoteMethodInvocation))要利用對象序列化運行遠程主機上的服務,就像在本地機上運行對象時同樣。.net

或使用套接字在網絡上傳送對象到另外一主機的程序來講,這些都是須要實現serializaiton機制的。對象序列化功能很是簡單、強大,在RMI、Socket、JMS、EJB都有應用。線程

Java對象序列化不只保留一個對象的數據,並且遞歸保存對象引用的每一個對象的數據。能夠將整個對象層次寫入字節流中,能夠將其保存在文件中或在網絡鏈接上傳遞。利用對象序列化能夠進行對象的「深複製」,即複製對象自己及引用的對象自己。序列化一個對象可能獲得整個對象序列。s設計

 

3、如何實現JAVA對象序列化?

類經過實現Java.io.Serializable接口能夠將類序列化。這個接口是一個製造者(marker)接口。也就是說,對於要實現它的類來講,該接口不須要實現任何方法。它主要用來通知Java虛擬機(JVM),須要將一個對象序列化。Java 序列化後的對象能夠轉換成字節流或從字節流恢復,不須要在類中增長任何代碼。只有極少數狀況下才須要定製代碼保存或恢復對象狀態。

 

注意:並不是全部類均可以序列化,

好比在cmd下,咱們輸入serialverJava.net.Socket,能夠獲得socket是否可序列化的信息,實際上socket是不可序列化的。

Java有不少基礎類已經實現了serializable接口,好比String,Vector等。可是好比hashtable就沒有實現serializable接口。

有些類是不能序列化的,例如涉及線程的類與特定JVM有很是複雜的關係。

 

4、JAVA序列化機制的原理:

將對象讀出或者寫入流的主要類有兩個:Java.io包的ObjectOutputStream與ObjectInputStream .

ObjectOutputStream將對象寫入字節流,提供用來將對象寫入輸出流的writeObject方法,

ObjectInputStream從字節流重構對象,提供從輸入流中讀出對象的readObject方法。

ObjectOutputStream類擴展DataOutput接口。

而使用這些方法的對象必須已經被序列化的。

writeObject() 用於對象序列化。若是對象包含其餘對象的引用,則writeObject()方法遞歸序列化這些對象。每一個 ObjectOutputStream維護序列化的對象引用表,防止發送同一對象的多個拷貝。因爲writeObject()能夠序列化整組交叉引用的對象,所以同一ObjectOutputStream實例可能不當心被請求序列化同一對象。這時進行反引用序列化,而不是再次寫入對象字節流。

定製序列化過程:

序列化一般能夠自動完成,但有時可能要對這個過程進行控制。java能夠將類聲明爲serializable,但仍可手工控制聲明爲static或transient的數據成員。

序列化時,類的全部數據成員應可序列化除了聲明爲transient或static的成員。將變量聲明爲transient告訴JVM咱們會負責將變量序列化。將數據成員聲明爲transient後,序列化過程就沒法將其加進對象字節流中,沒有從transient數據成員發送的數據。後面數據反序列化時, 要重建數據成員(由於它是類定義的一部分),但不包含任何數據,由於這個數據成員不向流中寫入任何數據。記住,對象流不序列化static或 transient。咱們的類要用writeObject()與readObject()方法以處理這些數據成員。使用writeObject()與 readObject()方法時,還要注意按寫入的順序讀取這些數據成員。

 

徹底定製序列化過程:

若是一個類要徹底負責本身的序列化,則實現Externalizable接口而不是Serializable接口。Externalizable接口定義包 括兩個方法writeExternal()與readExternal()。利用這些方法能夠控制對象數據成員如何寫入字節流.類實現 Externalizable時,頭寫入對象流中,而後類徹底負責序列化和恢復數據成員,除了頭之外,根本沒有自動序列化。這裏要注意了。聲明類實現 Externalizable接口會有重大的安全風險。writeExternal()與readExternal()方法聲明爲public,惡意類能夠用這些方法讀取和寫入對象數據。若是對象包含敏感信息,則要格外當心。這包括使用安全套接或加密整個字節流。到此爲至,咱們學習了序列化的基礎部分知識。

 

以上資料根據網絡資料整理而成,學習過程當中發現網上不少技術文檔條理性不是很清楚,結合我的理解整理,因爲採用有道筆記整理的緣由文章中不少原始出處已未知,望你們抱着分享的心態閱讀。

相關文章
相關標籤/搜索