1. 程式人生 > >Java 建立不可變物件-final關鍵字的使用總結

Java 建立不可變物件-final關鍵字的使用總結

之前一直對final這個關鍵的功能,很模糊。在程式設計中很多次都是使用eclispe自動在變數前加的final關鍵字,一直對這個好奇,今天找了些資料,對final進行地深入學習。
嚴格地說final修飾的變數不可被改變,一旦獲得了初始值,該final變數的值就不能被重新賦值,因此final修飾成員變數和修飾區域性變數時有一定的不同。

1. final成員變數

一般的成員變數是隨類初始化或物件初始化而初始化的。當類初始化時,系統會為該類的類field分配記憶體,並分配預設值。也就是說,當執行靜態初始化塊時可以對類Field賦初值;當執行普通初始化塊、構造器時可對例項Field賦初值。因此,成員變數的初始值可以在定義該變數時指定預設值,也可以在初始化塊、構造器中指定初始值。如果沒有在以上各種情況下對類成員變數賦初值,那麼系統將會給final 修飾的類成員變數,一個預設的值,比如:0、’\u0000’\、false或者null。(這時候其實final成員變數也就失去了存在的意義)。
歸納起來,使用final成員變數需要注意以下幾個問題:
靜態Field :必須在靜態初始化塊中或宣告該Field時指定初始值
普通Field:必須在非靜態初始化塊、宣告該Field或構造器中指定初始值
final修飾的類成員,程式設計師最好顯示地指定其初始值

2. final區域性變數
系統不會對區域性變數進行初始化,區域性變數必須由程式設計師顯示初始化。因此使用final修飾區域性變數時,既可以在定義時指定預設值,也可以不指定預設值。但是隻能初始化一次。

3. final修飾基本型別變數和引用型別變數的區別
1). 當final修飾基本變數型別時,不能對基本型別變數重新賦值,因此基本型別變數不能被改變
2). 當final修飾引用型別變數時,final只保證這個引用型別變數所引用的地址不會改變,即一直引用同一個物件,但是這個物件(物件的非final成員變數的值可以改變)完全可以發生改變

4. 可執行“巨集替換”的final變數


對於一個final變數來說,不管它是類field、例項field,還是區域性變數,只要該變數滿足3個條件,這個final變數就不再是一個變數,而是相當於一個直接量。
1). 使用final 修飾符修飾
2). 在定義該field變數時指定了初始值
3). 該初始值可以在編譯時就被確定下來

5. final修飾的方法不可以被重寫,final修飾的類不可以有子類