
示例中,普通域 i 寫被重排到構造函數外導致讀線程見到舊值,final 域 j 受規則保護必在構造函數內完成初始化,讀線程必見新值。

讀普通域被重排到讀引用前見到舊值,final 域受規則保護必在讀引用後讀取,見到初始化值。
對於 final int[] arr:
arr[0]=1),不能重排到構造函數外引用賦值之後arr[0]=2),不保證可見,存在數據競爭需額外同步
public FinalReferenceEscapeExample() {
i = 1; // 1 寫final域
obj = this; // 2 this引用逸出!此時對象未構造完成
}

操作 1、2 可能重排,導致其他線程通過逸出引用見到未初始化的 final 域。構造函數返回前,對象引用不可公開。
舊模型允許 final 域值「變化」:線程先見默認值 0,後見初始化值 1。最典型受害者是 String(char[] value + offset/count),舊模型下 String 可能出現值變化。新規則賦予 初始化安全性:正確構造的對象,無需同步即可保證所有線程見到 final 域初始化後的值。