*** 可能使用到final的三種情況:數據、方法和類 ***
*** 使用final的理由:設計的需要和運行效率 ***
一、final變量
- 一個永不改變的編譯時常量,也就是一經初始化將不能被改變;
- 可在編譯時帶入任何用到它的計算式進行執行,這種final常量必須是基本數據類型,並以關鍵字final表示,這將減輕一定的運行時負擔;
- 對於對象引用,final將使引用恆定不變,即一旦引用初始化指向一個對象將不能改爲指向另一個對象;
public class TestFinal{
private final String st="Hello Final";
public static void main(Stirng[] args){
st=new String();//報錯,st不能指向其他對象
st=new String("Error")//報錯
}
}
- 既有static又有final的域(即編譯期常量,其只佔用一段不能改變的存儲空間)將用大寫表示,並用下劃線分隔各個單詞;
public static final int NUM_MERBER=10;
- 在對常量進行定義的時候,必須對其進行賦值。(也就是在變量被送到編譯器中使用前必須賦值,可以在定義處和構造器處)
二、空白final
指聲明爲final但又未給定初值的域,但是編譯器又要求在使用前必須要初始化,所以一般會在構造器中進行初始化,這樣會使final更靈活,實例如下:
public class BlankFinal{
private final int i;
private final People p;
public BlankFinal(){ //通過構造器進行賦值
i=1;
p=new People(1);
}
public BlankFinal(int x){
i=x;
p=new People(x);
}
public static void main(String[] args){
new BlankFinal();
new BlankFinal(11);
}
}
class People{
private int i;
People(int i){this.i=i;}
}
三、final參數
final修飾的基本類型和引用類型可作爲參數進行傳遞,但是這些參數只能讀卻不能進行修改,實例如下:
public class TestFinal{
TestFinal(){}
void f(final TestFinal tf){
tf=new TestFinal();//報錯,因爲此時的引用tf已經指向了傳入的對象,不能再指向其他對象
}
void f(final int i){
i++;//報錯,此時i爲final常量不能改變
}
int f(final int i){
return i+1;//正確
}
}
final的這一特性主要用來向匿名內部類進行數據傳遞。
四、final方法
使用final方法的倆個原因:
*第一,把方法鎖定,以訪任何繼承類修改它的含義,即確保在繼承中使方法保持不變,並且不會被覆蓋。
第二,起初是通過此方式提高運行效率,因爲編譯器會將final方法進行內嵌調用。但是隨着Java版本的更新,效率問題主要依賴編譯器和JVM,所以現在更傾向於原因一。
要注意的一個點是:private方法其實默認的是final方法,所以private方法是不能被子類方法覆蓋的。
五、final類
在Java類添加final關鍵字的主要作用是使此類不能被任何類繼承(即此類不可能有任何子類),這種做法一般出於對安全因素的考慮。一旦這個類被定義爲final,那麼這個類中的所有域和方法都將隱式的被指定爲final。
***********************************************************************************
總而言之,用簡短的一句話描述就是:final變量不能被二次賦值,final方法不能被覆蓋,final類不能被繼承。