Java I/O---序列化介面Serializable

来源:https://www.cnblogs.com/zhuweiheng/archive/2017/12/30/8150986.html
-Advertisement-
Play Games

1.JDK API 中關於Serializable的描述 類通過實現 java.io.Serializable 介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。序列化介面沒有方法或欄位,僅用於標識可序列化的語義。 序列化運行時使用 ...


1.JDK API 中關於Serializable的描述

    public interface Serializable

        類通過實現 java.io.Serializable 介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。序列化介面沒有方法或欄位,僅用於標識可序列化的語義。

        序列化運行時使用一個稱為 serialVersionUID 的版本號與每個可序列化類相關聯,該序列號在反序列化過程中用於驗證序列化對象的發送者和接收者是否為該對象載入了與序列化相容的類。如果接收者載入的該對象的類的 serialVersionUID 與對應的發送者的類的版本號不同,則反序列化將會導致 InvalidClassException。可序列化類可以通過聲明名為serialVersionUID 的欄位(該欄位必須是靜態 (static)、最終 (final) 的 long 型欄位)顯式聲明其自己的 serialVersionUID

  1 ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

        如果可序列化類未顯式聲明 serialVersionUID,則序列化運行時將基於該類的各個方面計算該類的預設 serialVersionUID 值如“Java(TM) 對象序列化規範”中所述。不過,強烈建議 所有可序列化類都顯式聲明 serialVersionUID 值原因是計算預設的 serialVersionUID 對類的詳細信息具有較高的敏感性,根據編譯器(版本)實現的不同可能千差萬別,這樣在反序列化過程中可能會導致意外的 InvalidClassException因此,為保證 serialVersionUID 值跨不同 java 編譯器實現的一致性,序列化類必須聲明一個明確的 serialVersionUID 值。還強烈建議使用 private 修飾符顯示聲明 serialVersionUID(如果可能),原因是這種聲明僅應用於直接聲明類 -- serialVersionUID 欄位作為繼承成員沒有用處。數組類不能聲明一個明確的 serialVersionUID,因此它們總是具有預設的計算值,但是數組類沒有匹配 serialVersionUID 值的要求。

        下麵是一個舉例:

  1 /*
  2  * Person類的對象如果需要序列化,就需要實現Serializable標記介面。
  3  * 該介面給需要序列化的類,提供了一個序列版本號。serialVersionUID.
  4  * 該版本號的目的在於驗證序列化的對象和對應類是否版本匹配。
  5  *
  6  */
  7 public class Person implements Serializable {
  8 
  9 	/*
 10 	 * 給類顯示聲明一個序列版本號。
 11 	 */
 12 	private static final long serialVersionUID = 12324556L;
 13 	private static String name;
 14 	private transient/*瞬態*/ int age;
 15 
 16 	public Person() {
 17 		super();
 18 
 19 	}
 20 
 21 	public Person(String name, int age) {
 22 		super();
 23 		this.name = name;
 24 		this.age = age;
 25 	}
 26 
 27 	public String getName() {
 28 		return name;
 29 	}
 30 	public void setName(String name) {
 31 		this.name = name;
 32 	}
 33 	public int getAge() {
 34 		return age;
 35 	}
 36 	public void setAge(int age) {
 37 		this.age = age;
 38 	}
 39 
 40 	@Override
 41 	public String toString() {
 42 		return "Person [name=" + name + ", age=" + age + "]";
 43 	}
 44 
 45 
 46 }

2.serialVersionUID(串列化版本統一標識符)的作用

      在Java中,軟體的相容性是一個大問題,尤其在使用到對象串列性的時候,那麼在某一個對象已經被串列化了,可是這個對象又被修改後重新部署了,那麼在這種情況下, 用老軟體來讀取新文件格式雖然不是什麼難事,但是有可能丟失一些信息。 

       serialVersionUID來解決這些問題,預設 serialVersionUID 值是基於該類的各個方面計算的,理論上是一一映射關係,即唯一性。如果UID不一樣,無法實現發序列化,會得到異常InvalidClassException

        Java串列化機制定義的文件格式似乎很脆弱,只要稍微改動一下類的定義,原來保存的對象就可能無法讀取。例如,下麵是一個簡單的類定義: 

  1 public class Save implements Serializable
  2 {
  3     String name;
  4 
  5     public void save() throws IOException
  6     {
  7         FileOutputStream f = new FileOutputStream("foo");
  8         ObjectOutputStream oos = new ObjectOutputStream(f);
  9         oos.writeObject(this);
 10         oos.close();
 11     }
 12 }

        如果在這個類定義中增加一個域,例如final int val = 7;,再來讀取原來保存的對象,就會出現下麵的異常: 

  1 java.io.InvalidClassException:
  2 Save; local class incompatible:
  3 stream classdesc serialVersionUID = -2805284943658356093,
  4 local class serialVersionUID = 3419534311899376629

        上例異常信息中的數字串表示類定義里各種屬性的編碼值: 
        ●類的名字(Save)。 
        ●域的名字(name)。 
        ●方法的名字(Save)。 
        ●已實現的介面(Serializable)。 
        動上述任意一項內容(無論是增加或刪除),都會引起編碼值變化,從而引起類似的異常警報。這個數字序列稱為“串列化版本統一標識符”(serial version universal identifier),簡稱UID。解決這個問題的辦法是在類裡面新增一個域serialVersionUID,強制類仍舊使用原來的UID。新增的域必須是: 
        ●static:該域定義的屬性作用於整個類,而非特定的對象。 
        ●final:保證代碼運行期間該域不會被修改。 
        ●long:它是一個64位的數值。 
        也就是說,顯示的serialVersionUID必須定義成下麵這種形式:static final long serialVersionUID=-2805284943658356093L;。其中數字後面加上的L表示這是一個long值。 

2017-12-31

JAVA 對象序列化(一)——Serializable

serialVersionUID系列化和使用

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1排版 1 1相對獨立的程式塊之間、變數說明之後必須加空行。 示例:如下例子不符合規範。 if (!valid_ni(ni)) { ... // program code } repssn_ind = ssn_data[index].repssn_index; repssn_ni = ssn_dat ...
  • 本文主要介紹Spring中, 1 Bean 的 init-method 和 destroy-method 2 集合類型的裝配 3 註解方式裝配 4 以自動掃描把組件納入spring容器中管理 5 代理模式 一、Bean 的 init-method 和 destroy-method 以前在學Servl ...
  • 1.JDK API中RandomAccessFile類的描述 此類的實例支持對隨機訪問文件的讀取和寫入。隨機訪問文件的行為類似存儲在文件系統中的一個大型 byte 數組。存在指向該隱含數組的游標或索引,稱為文件指針;輸入操作從文件指針開始讀取位元組,並隨著對位元組的讀取而前移此文件指針。如果隨機訪問文件 ...
  • 字元流按字元個數輸入、輸出數據。 1.Reader類和FileReader類 Reader類是字元輸入流的超類,FileReader類是讀取字元的便捷類,此處的便捷是相對於其父類(另一個字元輸入流)InputStreamReader而言的。 read()每單字元讀取: read(char[] c)讀 ...
  • 概述 既然決定把視頻上老師講的實戰都自己動手實現一遍,那麼就先把最好大學排名這個實例自己寫一遍。看視頻的時候挺輕鬆的,但是到自己動手的時候才知道不容易,寫這個程式遇到兩個比較棘手的問題,一個是如何從網頁中提取出自己想要的信息,另一個是信息以什麼樣的形式保存並展示出來。其實幾乎所有的爬蟲都會遇到這兩個 ...
  • ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildPr ...
  • 1 class Person(): 2 def __init__(self, name): 3 self.name = name 4 5 6 def print_name(self): 7 print(self.name) 8 9 p = Person('Li') 10 import types 1... ...
  • 非原創,系轉載。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...