Java中的可序列化接口與示例
已發表: 2021-11-29Java 提供了幾個包,Serializable 接口就是其中之一。 它存在於 Java 包 java.io 中,是一種標記接口。 當定義為標記接口時,接口中不存在任何方法或字段。 因此,每當任何類實現接口時,接口都不需要實現任何方法。 如果類希望它們的實例被序列化或反序列化,則這些類實現接口。
序列化機制用於將對象狀態轉換為字節流。 該機制是通過使用 ObjectOutputStream 來實現的。 反序列化的過程與序列化的過程正好相反。 在這種情況下,字節流被轉換回 Java 的對象。 ObjectInputStream 用於反序列化。
目錄
序列化
將任何對象的狀態轉換為字節流稱為序列化。 而序列化的反面是反序列化。 Java 的對象可以轉換為靜態字節流。 然後可以將此靜態流保存在數據庫中,或者也可以將其傳輸到不同的網絡。 序列化的過程是實例相關的。 這意味著對象的序列化可以在一個平台上進行,然後對象的反序列化可以在另一個平台上進行。 為序列化過程實現了一種特定類型的標記接口“Serializable”。 因此,符合序列化條件的類,即Java 中的可序列化類,應該實現標記接口。
這種將對象狀態寫入字節流的機制稱為序列化。 該機制主要用於 JMS、EJB、JPA、RMI 和 Hibernate 技術。
ObjectInputStream 和 ObjectOutputStream 是擴展 java.io.InputStream 和 java.io.OutputStream 的高級類的形式。 原始類型和對像圖可以由 ObjectOutputStream 以字節形式寫入 OutputStream
溪流。 轉換產生的流可以通過 ObjectInputStream 讀取。 因此,對於序列化,從 ObjectOutputStream 調用方法 writeObject(),對於反序列化,從 ObjectInputStream 類調用方法 readObject()。

ObjectOutputStream中最重要的方法是:
上面這行代碼取自 https://www.baeldung.com/java-serialization。
在上面的代碼行中,取了一個可序列化的對象,然後將其轉換為流或字節流。
在 ObjectInputStream 的情況下,最關鍵的方法是:
上面這行代碼取自 https://www.baeldung.com/java-serialization。
上面這行代碼可以讀取字節序列並將這個字節流轉換為Java的對象。 原來的對象可以通過這個回退。
序列化過程的圖示可以描述如下:
考慮將“Person”類進行序列化。 靜態字段沒有序列化,它們屬於某些類。 在序列化過程中使用關鍵字“transient”可以忽略類字段。
資源
可以將 person 類型的對象保存到某個本地文件中,然後將值讀回。下面顯示的代碼可以用於此目的。
ObjectOutputStream 用於通過使用 FileOutputStream 將對象狀態保存到文件中。 在此示例中,已在項目目錄中創建了一個名為“yourfile.txt”的文件。 通過使用 FileInputStream,加載創建的文件。 然後這個流被 ObjectInputStream 拾取並轉換成一個名為 p2 的新對象。 最後測試加載的對象的狀態,並與原始對象的狀態匹配。 加載的對象必須明確地投射給典型的人。
Java 序列化的注意事項
一、繼承與組合
每當用戶實現接口 java.io.Serializable 時,所有實現該接口的類子類都變為可序列化的。 此外,如果一個對象持有對不同對象的引用,則引用來實現接口的對像是可單獨序列化的; 如果這些對像沒有實現接口,則會拋出異常。 拋出的異常將是 NotSerializableException。 此外,如果假設對像數組存儲在可序列化對像中,則所有數組對像都應序列化。 如果沒有發生對象的序列化,那麼它將拋出異常“NotSerializableException”。
2.序列版UID
對於實現 Serializable 接口的每個類,每個類都關聯一個數字。 該編號與 Java 虛擬機相關聯。 這主要是為了驗證加載和保存的對像是否具有確切的屬性。 只有當屬性相同時,對象才會在序列化時兼容。 IDE 會自動生成這些數字,並且主要基於類的名稱、其屬性以及與之關聯的訪問修飾符。 如果更改導致不同的數字,則會引發異常“InvalidClassException”。

如果可序列化類未聲明 serialVersionUID,JVM 將在運行時自動生成它。 雖然會自動生成數字,但仍然建議類聲明一個 serialVersionUID。 這是因為將自動生成的 serialVersionUID 將依賴於編譯器,並且有時可能會拋出意外的 InvalidClassExceptions。
3.自定義序列化
在 Java 中設置了一種默認方式來序列化對象。 Java 可以覆蓋此默認行為。 有一種自定義序列化的方法。 在嘗試序列化具有不可序列化屬性的對象的情況下,它特別有用。 此類對象的序列化可以通過用戶想要序列化的類中的兩種方法來完成。 這兩種方法是:
上面兩種方法都可以用來將屬性序列化成任何可以序列化的形式,之前是不可序列化的。
Java中序列化的優點
Java 中序列化的優點之一是對象的狀態可以在網絡上傳播。
Java 接口 java.io.Serializable
java.io.Serializable 是一個標記接口,這意味著接口中沒有方法和對象。 標記界面的主要功能是標記
Java 的類賦予類的所有對象特定的能力。 標記接口的示例是 Remote 和 Cloneable。
該接口必須由使用該接口序列化其對象的任何類實現。 默認情況下,包裝類和String類等類實現了接口java.io.Serializable。
下面顯示了一個 java 可序列化的示例。
在上面的代碼中,可以觀察到Student類實現了Serializable接口。 因此一旦類實現了 Serializable 接口,類中的對象就可以轉換為字節流。
ObjectOutputStream 類
此類用於將原始類型的數據和 Java 對象寫入 OutputStream。 支持接口 java.io.Serializable 的對象可用於寫入流。

ObjectInputStream 類
通過使用 ObjectOutputStream 寫入的所有原始數據都使用 ObjectInputStream 進行反序列化。
Java 中的 Serializable 接口示例如下所示。
在本例中,Student 類將被序列化。 ObjectOutputStream 類的 writeObject() 方法提供了序列化對象的所有功能。 對象的狀態保存在名為 f.txt 的文件中。
結論
本文討論了 Java 中的序列化概念。 它列出了序列化類對象所需的接口和其他重要方法。 序列化過程總是與每個可序列化類的 id 或數字相關聯。 此數字稱為 SerialVersionUID。 SerialVersionUID 的主要用途是驗證要序列化的對象的發送方和接收方。 這是因為發送者和接收者都應該是相同的。
它是 Java 編程語言的一個重要特性。 如果您想進一步了解 Java 中這些重要的特性和概念並掌握您的編程語言技能,您可以查看 upGrad 提供的軟件工程課程。 如果您是在職專業人士,該課程最適合您。 對於任何形式的查詢,可以聯繫我們的協助團隊。 您也可以瀏覽我們的網站了解具體課程並獲取詳細信息。 Serializable 接口是一個標記接口。 標記接口向 Java 運行時提供了一個提示,即實現類允許自己被序列化。 運行時將利用此接口序列化對象。 java中的可序列化接口是java中數據類實現的一種特殊接口。 當一個類實現了這個接口時,它可以被持久化在數據庫中。 該接口在 java.io 包中聲明。 Serializable 接口有兩個方法, readResolve() 和 writeReplace() ,用於讀取和寫入數據庫中的對象。 在Java中實現Serializable接口意味著擁有一個可以在任何具有Serializable接口的系統中序列化和反序列化的對象。 當類被第三方庫(JSON、XML 等)或網絡協議從外部序列化時,此類接口的實現將是有效的。 當一個變量被聲明為 Serializable 時,如果變量的每個實例作為參數傳遞給方法或從方法返回時,它將被序列化和反序列化。 序列化以編程方式執行,以便可以保留對象的狀態以供以後需要反序列化並呈現給對象的用戶時使用。 序列化對像是包含字節流的對象。 對象的構造函數或 writeObject() / readObject() 方法用於將字節流放入對像中。 存儲的數據可以是文本、音頻、視頻或任何自定義應用程序數據。 這些對象的數據可以存儲在文件中或遠程服務器上。 要通過網絡傳輸序列化對象,必須使用 RMI(遠程方法調用)協議。 RMI 是用於創建分佈式應用程序的良好協議。 它使客戶端能夠與在服務器上運行的 Java 應用程序中的對像上的方法進行通信。 RMI 協議是一種遠程過程調用 (RPC) 機制。 Java中的可序列化接口是什麼?
如果我們在 Java 中實現 Serializable 接口會發生什麼?
我們可以通過網絡傳輸序列化對象嗎?