Java 中的序列化:您需要知道的一切 [2022]

已發表: 2021-01-04

隨著 IT 行業的日益繁榮,我們對它的依賴似乎與日俱增。 這種穩定的增長促使許多在職專業人士開始使用編程語言,以期在行業內保持相關性。 雖然該行業使用多種語言為其客戶提供服務,但其中幾種語言的使用頻率高於其他語言。 Java 就是這樣一種語言。

無論您是新手還是老手,紮實的 Java 知識都將使您在軟件之旅的每一個轉折點上受益。 與任何其他編程語言一樣,Java 也包含自己的綜合教學大綱。 一個人必須每天練習這種語言,才能掌握所有標記語言的各種概念。 對用戶有很大幫助的一個概念是 Java 中的序列化實踐。

目錄

介紹

Java上下文中的序列化是指將Java代碼對象系統地轉換為字節流的過程。 這樣做是為了能夠將所述目標代碼從一個 Java 虛擬機高效地傳輸到另一個 Java 虛擬機。 隨後,這允許在反序列化的幫助下重新創建它。 我們使用序列化來滿足多個目標。 讓我們看一下以下部分中最受歡迎和相關的內容。

為什麼使用序列化?

將對象表示為字節序列的現像在編程範式中佔有相當大的份額。 當該過程本身也擴展到表示對象的數據時,實用程序會增加許多倍。 下面列出了 Java 中序列化的一些最常見用途。

溝通

Java 中的序列化允許在多個計算機系統之間進行有效和迅速的通信。 這些單元利用對象序列化和傳輸來促進各種對象的同時共享和設計。 因此,這也會導致最終的順利執行。 在海量數據庫的情況下,序列化允許高度簡化的對象處理方法。

緩存

從廣義上講,緩存是指通過在信息上投入最少的時間來存儲信息以便稍後訪問信息的方法。 Java 中的序列化通過最小化反序列化大對象所消耗的時間來提示緩存。 眾所周知,與反序列化所需的時間相比,構建對象所花費的時間要多得多。 因此,序列化通過緩存混合中相對較大的對象來幫助優化這種時間消耗。

深拷貝

Java 中的深拷貝是指從樹中復制對象的過程,該過程不依賴於可能會發生一定程度變化的任何先前版本。 通過採用序列化,這個克隆過程變得更加容易。 通過將對象序列化為字節數組,然後對其進行反序列化,用戶可以獲得所述對象的副本。

跨 Java 虛擬機同步

實踐序列化的主要優勢在於它使用戶能夠跨不同的 JVM 進行操作。 一旦採用序列化,這些 JVM 是否在相同或不同的架構和操作系統上工作都沒有關係。

持久性

通過對對象應用序列化,可以直接存儲項目的狀態,而不會帶來任何不便。 此外,它還允許用戶將提及的狀態保存在數據庫中,以便以後在將來的任何時間點檢索。

閱讀:Java 序列化面試問答

序列化對象 - 涉及的過程

在繼續序列化對象之前,我們首先需要確定它是否可序列化。 現在,我們如何確定呢? 當且僅當其類或其任何父類允許實現 java.io.Serializable 接口時,Java 中的對象才是可序列化的。 如果這些類也實現了它的子接口,也就是 java.io.Externalizable,那麼也符合標準。

如上所述,跨 JVM 同步是使用序列化最有效的應用之一。 當我們序列化一個對象時,我們將這個對象的狀態轉換為字節流。 因此,我們可以將對像從一個 Java 虛擬機轉移到另一個。 因此,這個字節流也可以轉換回原始對象。

這種轉換也稱為反序列化。 它是序列化的逆過程,其中來自發送方的對象的字節流之前已經序列化,在接收端重新創建。

Java中序列化的優點

在前面幾節討論序列化的用途和應用時,我們已經闡明了它的各種優點。 現在是深入研究它們的時候了。

  • 序列化最顯著的優勢之一是它是一個內置功能。 要實現或執行序列化,您不需要藉助任何第三方軟件。
  • 即使對於初學者並且剛剛學習他們的繩索的用戶來說,序列化也是一個相當容易學習和理解的過程。
  • 通常,來自不同編程背景的開發人員在必須處理新語言的細微差別時會接觸到背景。 但是,在序列化的情況下,該過程是通用的,因此所有開發人員都非常熟悉。
  • 它不僅易於使用和實施,而且同樣易於定制。
  • 目前,有許多關鍵技術在其操作中使用序列化。 這是因為被序列化的數據流支持加密、認證、壓縮和安全的 java 計算。

Java中序列化的缺點

沒有一種編程語言是百分百完美的,它們也不能聲稱是完美的。 因此,構成它們的概念和過程也並非沒有自己的缺陷。 以下是與序列化過程相關的一些一般缺點。

  • 一些序列化過程也需要同時應用反序列化。 現在,應用反序列化的缺點是它會使對像變脆。 因此,永遠無法完全確定所述對像是否會被有效地反序列化。
  • 當調用序列化過程時,會導致創建一堆瞬態變量。 這些瞬態變量在創建時會佔用額外的內存空間。 但是,由於在這些過程中未調用構造函數,因此許多這些瞬態變量無法初始化。 隨後,它們最終影響了標準 Java 流程的變體。
  • 對於所有的時間消耗優化,序列化過程在內存利用率方面越來越低效。
  • 序列化過程不為每個 Java 標準版提供任何轉換控制機制。 因此,它不適合與需要並行訪問而不需要第三方 API 的應用程序結合使用。
  • 在使用序列化時,通常必須在獲得細粒度控制以訪問對象方面做出妥協。

從實用的角度看序列化

到目前為止,我們已經將序列化過程作為一個理論概念進行了討論,包括它的各種優點和缺點。 現在是深入討論允許我們從實際角度可視化序列化及其實現的時候了。 下面列舉幾個案例,幫助我們理解序列化的實際實現。

必讀:JavaBeans 屬性和好處:你應該如何利用?

序列化和繼承

Java中的繼承被廣泛定義為一個類獲取或繼承另一個類的方法和字段的現象。 繼承屬性的類稱為子類,繼承屬性的類稱為超類。 術語超類也可以與基類和父類互換使用。

我們的第一個案例處理超類上下文中的序列化。 一般來說,如果一個超類是可序列化的,那麼它的子類也可以默認被認為是可序列化的。 當然,這只有在超類實現 Serializable 接口時才成立。 但是,在某些情況下,即使超類沒有實現 Serializable 接口,子類也可以被序列化。

當子類設法以一種能力實現 Serializable 接口時,就會發生這種情況。 如果超類在任何情況下都沒有實現Serializable接口,那麼子類的對象可以在子類自己實現Serializable接口時手動序列化。

有時,用戶也可能遇到第三種可能性。 當超類是可序列化的,但用戶並不完全需要採用與子類相關的過程時,就會出現這種可能性。

在這樣的情況下,有一些方法可以有意識地防止不需要的子類序列化。 這可以通過在子類中實現 writeObject() 和 readObject() 方法來完成。 然而,僅僅實現這些方法是不夠的。 除了編寫這些方法外,用戶還必須確保上述方法不會從其實現中拋出 NotSerializableException。

在靜態成員的幫助下進行序列化

當實現序列化過程時,它最終會忽略過程中的靜態字段成員。 這主要是因為序列化作為一個過程在很大程度上與所討論對象的最新狀態有關。 結果,雖然與類的特定實例關聯的數據被成功序列化,但與之相關的靜態成員字段卻沒有。

關於 XML 文檔的序列化

Java 對像到 XML 的序列化可以通過多種方式實現。 它們主要是在 XMLEncoder 和 XMLDecoder 的幫助下實現的。 將 Java 對象序列化為 XML 文檔的主要目的在於嘗試限制序列化過程固有的各種缺點。

序列化過程中最相關的問題之一是保存和恢復序列化對象的邏輯僅基於組成類的內部結構。 它沒有考慮在保存對象和檢索對象之間經過的時間內可能對這些類造成的任何更改。 隨後,這將導致反序列化過程即將失敗。

序列化也會引起版本控制問題。 當用戶使用類的一個版本保存對象但嘗試使用不同版本或新版本的類來反序列化同一類時,就會發生這種情況。 在這種情況下,反序列化過程也會失敗。

因此,為了避免所有這些問題,一些用戶更喜歡將對象序列化為 XML 文檔,而不是採用將它們序列化為二進制格式的傳統方法。 此外,將 Java 對象序列化為 XML 文檔還可以確保對像變得可讀,從而提高了便利性。

結帳:Java 面試問答

了解可外部化接口

Java 中的 Externalizable 接口與序列化接口非常相似。 不同之處在於它們提供定制序列化的能力。 externalizable 接口使您可以選擇要存儲在流中的對象,而序列化接口不授予您相同的權限。

可以利用 java.io 下的可外部化接口。 externalizable 接口也為用戶提供了兩種方法。 第一個是 public void writeExternal(ObjectOutput out) throws IOException。 另一種是 public void readExternal(ObjectOutput in) throws IOException。

序列化和外化的區別

除了提供定制序列化的能力之外,其他一些關鍵變量也將序列化和外部化區分開來。 以下部分將仔細研究它們。

執行

可序列化接口和可外部化接口之間的主要區別之一在於它們的實現。 externalizable 接口期望用戶明確提及他們希望被序列化的對象。 當處理可序列化接口時,情況並非如此。 在可序列化接口中,所有對象和變量在運行時都被序列化,沒有任何區別。

方法

Externalizable 接口主要由兩個方法組成。 它們是 writeExternal() 方法和 readExternal() 方法。 另一方面,可序列化接口不包含任何方法。

過程

在可外部化的接口中執行序列化過程時,他們被賦予了自定義序列化的特權。 而在可序列化接口中,人們已經將自己置於默認的序列化過程中。

向後兼容性和控制

Externalizable 接口支持序列化,對相關版本控制沒有任何保留。 這種方法的唯一問題是用戶在序列化超類時必須對自己負責。 相反,序列化接口要求兩端都存在相同版本的 JVM。 但是,它確實允許所有對象和類的默認序列化,包括超類。

公共無參數構造函數

在重構序列化對象時,外部化接口需要使用公共無參數構造函數。 這在序列化接口的情況下是不同的,它不明確需要無參數構造函數,而是利用反射來重構序列化的對象和類。

Java中的序列化:爭議

有不少爭議與 Java 中的序列化概念相關。 他們中的許多人首先關心的是刪除序列化作為一個過程。 人們普遍認為,Oracle 的架構師長期以來一直在考慮從 Java 中刪除序列化,因為他們認為這是 1997 年的一個可怕錯誤。

根據他們的研究,序列化過程的設計缺陷使得它們對數據本身構成威脅。 就此而言,Mark Reinhold 在 1997 年將幾乎三分之一的 Java 漏洞歸因於序列化過程,甚至表示商數也可能遠不止於此。

因此,很有可能在即將到來的更新中,序列化作為一種結構將完全從 Java 的編年史中刪除或替換。 這也可能是因為大多數專家不認為序列化是 Java 初學者可以在他們的項目中實現的理想選擇。

另請閱讀: Java 項目理念和主題

從世界頂級大學獲得軟件開發課程獲得行政 PG 課程、高級證書課程或碩士課程,以加快您的職業生涯。

結論

對序列化的討論和審議不能通過闡明一些最佳實踐來結束。 以下是用戶必須採用的一些方法,以確保為自己提供最佳體驗。

  • 為了表示可序列化的字段,必須使用 javadoc@serial 標記。
  • 對於表示序列化對象的文件,最好使用 .ser 擴展名。
  • 通常,對靜態或瞬態字段進行默認序列化的過程是不受歡迎的。
  • 除非絕對強制,否則在任何情況下都必須盡量避免可擴展類的序列化。
  • 在實現序列化時,必須確保避免內部類參與序列化過程。

如果您有興趣了解有關 Java、OOP 和全棧軟件開發的更多信息,請查看 upGrad 和 IIIT-B 的全棧軟件開發執行 PG 計劃,該計劃專為工作專業人士設計,提供 500 多個小時的嚴格培訓, 9 個以上的項目和任務、IIIT-B 校友身份、實用的實踐頂點項目和頂級公司的工作協助

為未來的職業做準備

立即申請軟件工程碩士