首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 序列化陷阱:final 基本型別欄位在反序列化時的行為

     編輯:Java 綜合教學

Java 每日一題:final 欄位與序列化的互動

在 Java 序列化機制中,final 修飾的基本型別欄位往往被視為不可變常數,但在反序列化過程中,其行為可能出乎意料。這道經典題目探討的正是這一點。

程式碼片段

package Nov2016;
import java.io.Serializable;

public class Ques1111 implements Serializable {
    private static final long serialVersionUID = 1L;
    public final int num = 123;
}

問題情境

將 Ques1111 物件序列化並寫入磁碟。隨後,直接修改磁碟上的序列化資料,將 num 欄位的值從 123 改為 321。當再次反序列化該資料時,得到的物件中 num 的值將是多少?

核心解析

Java 序列化規範規定,final 基本型別欄位(如 int、long 等)在序列化時會寫入其數值。反序列化時,JVM 會透過反射機制直接賦值給該欄位,而不會呼叫建構子。因此,若序列化資料流中的位元組被竄改,反序列化出來的物件將攜帶被修改後的值。

答案:321

深度補充

  • final 參考型別:若欄位為 final 物件參考,反序列化同樣會重新綁定參考,但物件本身的不可變性取決於該物件類別的設計。
  • 安全性啟示:序列化資料不應被視為受信任輸入。敏感資料建議加簽或加密,防止惡意篡改導致業務邏輯繞過驗證。
  • serialVersionUID:範例中顯式宣告 serialVersionUID,確保跨版本反序列化的一致性,避免 InvalidClassException。

這道題為後續探討「序列化代理模式」與「writeReplace/readResolve」鋪墊,掌握 final 欄位反序列化語意是理解進階序列化技巧的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved