1. 程式人生 > >Final 關鍵字

Final 關鍵字

pre oid 證明 can 自動 表達 定義 private 體積

1、涵義

最一般的意思就是聲明 “這個東西不能改變”。之所以要禁止改變,可能是考慮到兩方面的因素:設計或效率。 final 關鍵字可以用來修飾變量、方法和類,修飾變量表示變量不能被修改,修飾方法表示方法不能被重寫,修飾類表示類不能被繼承。

2、修飾變量

對於基本數據類型, final 會將值變成一個常數;但對於對象引用, final 會將引用變成一個常數。進行聲明時,必須將引用初始化到一個具體的對象。而且永遠不能將引用變成指向另一個對象。來個Demo 如下:

public class Value
{
    int i=1;
}
public class FinalData
{
    
final int i1 = 9; static final int I2 = 99; public static final int I3 = 39; final int i4 = (int)(Math.random()*20);//特別註意 static final int i5 = (int)(Math.random()*20);//特別註意 Value v1 = new Value(); final Value v2 = new Value(); static final Value v3 = new Value(); final int
[] a = { 1, 2, 3, 4, 5, 6 }; public void print(String id) { System.out.println(id + ": " + "i4 = " + i4 + ", i5 = " + i5); } public static void main(String[] args) { FinalData fd1 = new FinalData(); //! fd1.i1++; // Error:final的值不能被改變 fd1.v2.i++; // 對象的成員未被設成final,不會報錯
fd1.v1 = new Value(); // OK --不是final對象 for(int i = 0; i < fd1.a.length; i++) fd1.a[i]++; // 對象的成員未被設成final,不會報錯 // fd1.v2 = new Value(); // Error: Can‘t // fd1.v3 = new Value(); // 不能將一個final引用指向另一個 // fd1.a = new int[3]; fd1.print("fd1"); System.out.println("Creating new FinalData"); FinalData fd2 = new FinalData(); fd1.print("fd1"); fd2.print("fd2"); } }

技術分享

技術分享

不能由於某樣東西的屬性是 final,就認定它的值能在編譯時期知道。 i4 和 i5 向大家證明了這一點。它們在運行期間使用隨機生成的數字。例子的這一部分也向大家揭示出將final 值設為 static 和非 static 之間的差異 。記住一點:static局部變量在所處模塊在初次運行時進行初始化工作,且只操作一次。

3、空白Final Java強行要求我們對 final 進行賦值處理—— 要麽在定義字段時使用一個表達 式,要麽在每個構建器中。這樣就可以確保 final 字段在使用前獲得正確的初始化。
4、修飾方法 之所以要使用 final 方法,可能是出於對兩方面理由的考慮:
1、為方法“上鎖”,防止任何繼承類改變它的本來含義。設計程序時,若希望一個方法的行為在繼承期間保持不變,而且不可被覆蓋或改寫,就可以采取這種做法。 2、將一個方法設成 final 後,編譯器就可以把對那個方法的所有調用都置入“嵌入”調用裏。只要編譯器發現一個 final 方法調用,就會(根據它自己的判斷)忽略為執行方法調用機制而采取的常規代碼插入方法(將自變量壓入堆棧;跳至方法代碼並執行它;跳回來;清除堆棧自變量;最後對返回值進行處理)。相反,它會用方法主體內實際代碼的一個副本來替換方法調用。這樣做可避免方法調用時的系統開銷。當然,若方法體積太大,那麽程序也會變得雍腫,可能受到到不到嵌入代碼所帶來的任何性能提升。因為任何提升都被花在方法內部的時間抵消了。 Java 編譯器能自動偵測這些情況,並頗為“明智”地決定是否嵌入一個 final 方法。然而,最好還是不要完全相信編譯器能正確地作出所有判斷。通常,只有在方法的代碼量非常少,或者想明確禁止方法被覆蓋的時候,才應考慮將一個方法設為final。 類內所有 private 方法都自動成為 final。由於我們不能訪問一個 private 方法,所以它絕對不會被其他方法覆蓋。

5、修飾類 如果說整個類都是 final(在它的定義前冠以 final 關鍵字),就表明自己不希望從這個類繼承,或者不允許其他任何人采取這種操作。換言之,出於這樣或那樣的原因,我們的類肯定不需要進行任何改變;或者出於安全方面的理由,我們不希望進行子類化(子類處理)。
Final 類的所有方法都默認是final修飾的。



Final 關鍵字