package Nov2016;
import java.io.Serializable;
public class Ques1115 implements Serializable {
private static final long serialVersionUID = 1L;
public final int num = init(); // 通過方法賦值
public int init() {
return 123;
}
}
init() 返回值為 321(保持 serialVersionUID 不變)。num 的值是多少?Java 序列化規範對 final 修飾的實例變量有特殊處理:
static final 基本類型或 String,且賦值為常量表達式):序列化時不寫入流中,反序列化時直接使用類中定義的常量值。本題中 num = init() 屬於「運行時賦值」,因此序列化時將 123 寫入流。
輸出結果為 123。
反序列化時,JVM 從對象流讀取已存儲的 123 賦給 num,完全跳過當前類定義中的 init() 邏輯(即便已改為返回 321)。這保證了「對象狀態的持久化一致性」。
前一天題目中 num 在構造器賦值(public Ques1114(){ num = 123; }),同屬「運行時賦值」,行為一致,反序列化同樣輸出 123。
final或改用 transient + 反序列化後重新計算。serialVersionUID,否則會拋出 InvalidClassException。理解此機制,有助於避免分布式系統中因序列化不一致導致的難以排查的業務 Bug。