java序列化的接口为什么是空的?
Java序列化是JDK1.1時引入的一組開創性的特性,用于將Java對象轉換為字節數組,便于存儲或傳輸。此后,仍然可以將字節數組轉換回Java對象原有的狀態。
序列化的思想是“凍結”對象狀態,然后寫到磁盤或者在網絡中傳輸;反序列化的思想是“解凍”對象狀態,重新獲得可用的 Java 對象。
再來看看序列化 Serializbale 接口的定義:
public interface Serializable { }Serializable 接口之所以定義為空,是因為它只起到了一個標識的作用,告訴程序實現了它的對象是可以被序列化的,但真正序列化和反序列化的操作并不需要它來完成。
java.io.ObjectOutputStream是實現序列化的關鍵類,它可以將一個對象轉換成二進制流,然后可以通過ObjectInputStream將二進制流還原成對象。
ObjectOutputStream在序列化過程中會依次調用: writeObject() → writeObject() → writeOrdinaryObject() → writeSerialData() → defaultWriteFields()ObjectInputStream的反序列化過程: readObject() →readObject() → readOrdinaryObject() →readSerialData() → defaultReadFields()static 和 transient 修飾的字段是不會被序列化的。
首先,在 Wanger 類中增加兩個字段。
其次,在測試類中打印序列化前和反序列化后的對象,并在序列化后和反序列化前改變 static 字段的值。具體代碼如下:
從結果的對比當中,我們可以發現:
1)序列化前,pre 的值為“沉默”,序列化后,pre 的值修改為“不沉默”,反序列化后,pre 的值為“不沉默”,而不是序列化前的狀態“沉默”。
為什么呢?因為序列化保存的是對象的狀態,而 static 修飾的字段屬于類的狀態,因此可以證明序列化并不保存 static 修飾的字段。
2)序列化前,meizi 的值為“王三”,反序列化后,meizi 的值為 null,而不是序列化前的狀態“王三”。
為什么呢?transient 的中文字義為“臨時的”(論英語的重要性),它可以阻止字段被序列化到文件中,在被反序列化后,transient 字段的值被設為初始值,比如 int 型的初始值為 0,對象型的初始值為 null。
很多人覺得自己寫得 Java 代碼中,新建的 pojo 對象要實現序列化是為了要保存到硬盤上,但是,實現序列化和保存到硬盤上沒有必然的關系。
假設左邊的是你的電腦,也就是客戶端,右邊的是服務器。之前你的客戶端和服務器可能都在同一個電腦上,都是 Windows 下,那么右邊的服務器也可以放到 Linux 中,這就涉及到左右兩個不同的服務器了。中間用一條豎線分隔一下。
客戶端可以調用服務器,所以肯定要傳遞參數。假設你傳遞的是字符串,沒有問題,所有的機器都可以識別正常的字符串。
那么現在假設你傳遞的參數是一個 Java 對象,比如叫 cat。服務器并沒有那么智能,它并不會知道你傳遞的是一個 Java 對象,而不是其他類型的數據,它識別不了 Java 對象。
Java 對象本質上是 class 字節碼,服務器并不能根據這個字節碼識別出該 Java 對象。所以,要提供一個公共的格式,不僅 Windows 能識別,你的服務器也能識別的公共的格式。
我們將 Java 對象轉換成公共的格式叫做序列化,將公共的格式轉換成對象叫做反序列化。保存到磁盤只是序列化的一種表現形式。
序列化其實很好理解,假如你現在做一個項目,項目是分工合作的,并且你喝其他小組成員不在同一個城市,那么你要如何把你寫的那些類給其他小組成員呢?這個時候就要用到序列化了,簡單的說:序列化就是將內存中的類或者對象(你寫的類都是存儲在內存中的)變成可以存儲到存儲媒介中的流,你將類序列化成流之后可以通過互聯網傳輸給別人,你也可以反序列化將別人的序列化流轉換成內存中的對象
總結
以上是生活随笔為你收集整理的java序列化的接口为什么是空的?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无人机边缘计算中的计算卸载——Stack
- 下一篇: Egret MovieClip2