首先,我們可以從字面上理解一下final這個英文單詞的中文含義:“最後的,最終的; 決定性的; 不可更改的;”。顯然,final關鍵詞如果用中文來解釋,“不可更改的”更為合適。當你在編寫程式,可能會遇到這樣的情況:我想定義一個變數,它可以被初始化,但是它不能被更改。 例如我現在想要定義一個變數保存圓 ...
首先,我們可以從字面上理解一下final這個英文單詞的中文含義:“最後的,最終的; 決定性的; 不可更改的;”。顯然,final關鍵詞如果用中文來解釋,“不可更改的”更為合適。當你在編寫程式,可能會遇到這樣的情況:我想定義一個變數,它可以被初始化,但是它不能被更改。
例如我現在想要定義一個變數保存圓周率的值,作為一個客觀的、正確性有保障的值,如果在後序程式中更改它,可能會造成結果的錯誤,甚至程式的崩潰。那麼這個時候final關鍵字就可以發揮它的用處了。不過,final不僅僅可以用來修飾數值,它還有其他的用法,看過下麵的實例應該會有個基本的瞭解。
如有錯誤,歡迎批評指正。
1.用final來修飾數據
1.1用final來修飾數值:
//例1
public class Demo{
public static void main(String[]args){
final double PI=3.14;
System.out.println(PI);
PI=3.1;
System.out.println(PI);
}
}
如例1所示,如果修改final修飾的變數PI,會發生什麼呢?
好吧,編譯都不能通過,說明final修飾過後的數值變數是不能改變的。
現在又有一個疑問,如果final定義的變數,沒有初始化,會不會報錯?見例2:
//例2
public class Demo{
public static void main(String[]args){
final double PI;
System.out.println(PI);
}
}
還是會報錯,其實這個和fina的關係不大,僅僅因為沒有賦值,就算沒有final,也是會報錯(親測)。
1.2上面說的是數值,如果final修飾的是對象呢?
//例3
public class Demo{
public static void main(String[]args){
final Cat cat1=new Cat(1);
Cat cat2=new Cat(2);
cat1=cat2;
}
}
class Cat{
private int id=0;
private int age=0;
Cat(int id){this.id=id;}
public void setAge(int age){
this.age=age;
}
}
編譯依然通不過。
但是cat1長大一歲了,我想修改一下他的年齡,可不可以呢,貼一段測試代碼:
//例4
public class Demo{
public static void main(String[]args){
final Cat cat1=new Cat(1);
//Cat cat2=new Cat(2);
cat1.setAge(1);
System.out.println(cat1.getAge());
}
}
class Cat{
private int id=0;
private int age=0;
Cat(int id){this.id=id;}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
}
運行結果:
編譯運行都毫無障礙。說明什麼呢?當用final來修飾對象時,不能改變對象的引用,但是可以修改對象的屬性值。cat1只能指向id為1的貓,如果讓它指向cat2所指的貓,編譯器會報錯(例3)。
1.3用final來修飾參數
當final來修飾形參時,形參也是不能被更改的,例如我在獲取年齡的時候,偷偷地改一下ID:
public class Demo{
public static void main(String[]args){
Cat cat1=new Cat(1);
System.out.println(cat1.getAge(1));
}
}
class Cat{
private int id=0;
private int age=0;
Cat(int id){this.id=id;}
public void setAge(int age){
this.age=age;
}
public int getAge(final int id){
id++;
return this.age;
}
}
果然報錯了!
2.final修飾方法(函數)的時候
一般用final修飾方法的目的是:鎖住方法,防止繼承它的類來修改(覆蓋)它。例如Cat類是動物,所以它繼承了動物類Animal,但是每個動物都有規定:不能傷害人類,所以Animal的rule方法用final修飾一下,不允許繼承者們修改,代碼如下:
public class Demo{
public static void main(String[]args){
Cat cat1=new Cat(1);
cat1.rule();
//System.out.println(cat1.getAge());
}
}
class Animal{
public final void rule(){
System.out.println("do not hurt people!");
}
}
class Cat extends Animal{
private int id=0;
private int age=0;
Cat(int id){this.id=id;}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
public final void rule(){
System.out.println("I want to hurt people!");
}
}
當我嘗試覆蓋基類方法時,失敗了。當然,例子舉的是public修飾的方法,但如果是private修飾的方法,本身對子類就不可見,更別說覆蓋了。
3. 用final來修飾類:
用final來修飾類的時,說明這個類從設計之初,就不打算用來被繼承,換句話說,也不允許其他人來繼承這個類,從而保證安全性。例如我在Animal類前加個final
編譯報出的錯誤很明確:無法被繼承。
4.final 和 static的區別
用final修飾,主要是為了表現“不可修改性”,從而提高安全性 。而static重點在於共用,方便。在類里創建一個static修飾的函數,則可以直接通過類名訪問,該類new出來的對象,也可以共用static函數,或者static修飾的共有屬性。
static的具體用法,可參考:http://www.cnblogs.com/dolphin0520/p/3799052.html。