1. 程式人生 > >解析Java中final關鍵字的各種用法

解析Java中final關鍵字的各種用法

col 後序 blog str 訪問 人類 依然 fin 可能

首先,我們可以從字面上理解一下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。

解析Java中final關鍵字的各種用法