歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java序列化機制

Java序列化機制

日期:2017/3/1 9:51:48   编辑:Linux編程

Java序列化機制的主要目的是將內存中的對象轉換成字節流,然後傳輸到其它的系統,並在其它系統中將字節流重新生成對象。典型的應用場景就是Java分布式系統,在一個JVM中創建的對象經常要通過網絡等傳輸到另外一個JVM中。因此在Java分布式中,序列化是非常重要的一環。

Java語言提供序列化對象方式有兩種:

實現 Serializable接口;這是系統的默認實現

實現 Externalizable,並實現其中的writeExternal(ObjectOutput out) 和 readExternal(ObjectInput in)方法。

Java序列化的規則 一個對象實現Serializable接口時,便具備了序列化的能力。但是查看Serializable接口的源碼時,卻會發現它是一個空接口,也就是說它只是標識作用,這與Java 1.5產生的Annotation功能類似。那JVM的默認序列化機制是怎麼工作的呢?

其實Java語言本身定義序列化的規則:

類必須實現Serializable接口,或其父類實現了Serializable接口。

當一個對象被序列化時,從當前類開始的整個父級繼承鏈上的對象都會被序列化,直到第一個沒有實現Serializable接口的類O。如果該類沒有繼承關系,這個O就是是Object類。 規則1中的類O,必須包含一個無參數的構造函數。

在反序列化時,對象會通過之前序列化的數據完成實例化,不會調用構造函數。由於Java實例化時,其父類會被先實例化,因此遇到第一個沒有實現Serializable的類,這時必須調用其無參構造函數完成對象實例化。

關於serialVersionUID 網絡對象第一次上線使用時,需要設定serialVersionUID。serialVersionUID在《Java語言規范》有固定算法,跟類中各field的定義相關,如果沒有顯式賦值,JVM會默認算出一個進行網絡傳輸。如果沒有顯式賦值,在你增減了field/修改了定義的情況下,serialVersionUID已被改變,這時新舊序列化後的字節流就不兼容了,反序列化時將會出現問題。沒定義serialVersionUID,而又發生了serialVersionUID變化,網絡兩端只有所有機器都停掉,並且先後起有順序時,才能不出絲毫差錯。

static和transient修飾的字段不會被序列化。

序列化協議 Java語言規范中定義了默認的對象序列化協議–即將對象轉換成字節流的協議。http://docs.Oracle.com/javase/1.5.0/docs/guide/serialization/spec/protocol.html 其實我們還可以使用其它的序列化協議,比如Google的Protobuf等。

Copyright © Linux教程網 All Rights Reserved