天天看點

final關鍵字1 修飾屬性或者變量2 修飾方法3 修飾類4 final關鍵字的好處5 不可變類6其他重要知識點

1 修飾屬性或者變量

無論屬性是基本類型還是引用類型,作用都是變量裡面存放的“值”不可變

經常和static關鍵字一起使用,作為常量

  • 基本類型,變量放的是實實在在的值,如1,“abc”等
  • 引用類型,變量放的是個位址,是以用final修飾引用類型變量指的是它裡面的位址不能變,即它隻能指向初始時指向的那個對象,而不關心指向的對象内容的變化

是以修飾的變量必須被初始化

public static final String LOAN = "loan";
LOAN = new String("loan") //invalid compilation error      
  • 定義時
  • 初始化塊中,但不可在靜态初始化塊中,靜态的final執行個體變量才可以在靜态初始化塊中
  • 構造方法中,但靜态final執行個體變量不可以在其中

final變量是隻讀的

2 修飾方法

該方法可被繼承,但不許被任何子類重寫

當調用final方法時,直接将方法主體插入到調用處,而不是進行方法調用,這樣能提高程式效率(内聯機制)

如果你認為一個方法的功能已經足夠完整了,子類中不需要改變的話,你可以聲明此方法為final

final方法比非final方法快,因為在編譯時候已靜态綁定了,不需要在運作時再動态綁定。

class PersonalLoan{
    public final String getName(){
        return "personal loan";
    }
}

class CheapPersonalLoan extends PersonalLoan{
    @Override
    public final String getName(){
        return "cheap personal loan"; //compilation error: overridden method is final
    }
}      

3 修飾類

使用final來修飾的類叫作final類

final類通常功能是完整的,不能被繼承

Java中有許多類是final的,譬如String, Interger以及其他包裝類

類不可以被繼承,但這并非表示final類的執行個體變量也不可變,除非給執行個體變量也增加final修飾

final class PersonalLoan{
}

class CheapPersonalLoan extends PersonalLoan{  //compilation error: cannot inherit from final class

}      
final class PersonalLoan{
}

class CheapPersonalLoan extends PersonalLoan{  //compilation error: cannot inherit from final class

}      

一個類不可同時被abstract和final修飾

思考一個有趣的現象:

byte b1=1;
byte b2=3;
byte b3=b1+b2;  //當程式執行到這一行的時候會出錯,因為b1、b2可以自動轉換成int類型的變量,運算時java虛拟機對它進行了轉換,結果導緻把一個int指派給byte
final byte b1=1;
final byte b2=3;
byte b3=b1+b2;  //不會出錯,相信你看了上面的解釋就知道原因了。      

4 final關鍵字的好處

  • 提高性能

    JVM和Java應用都會緩存final變量。

  • final變量可以安全的在多線程環境下進行共享,而不需要額外的同步開銷。
  • 使用final關鍵字,JVM會對方法、變量及類進行優化。

5 不可變類

建立不可變類要使用final關鍵字。不可變類是指它的對象一旦被建立了就不能被更改了。String是不可變類的代表。不可變類有很多好處,譬如它們的對象是隻讀的,可以在多線程環境下安全的共享,不用額外的同步開銷等等。

6其他重要知識點

不能夠對final變量再指派

本地變量必須在聲明時指派

在匿名類中所有變量都必須final

final關鍵字不同于finally關鍵字,後者用于異常處理

final關鍵字容易與finalize()方法搞混,後者是在Object類中定義的方法,是在垃圾回收之前被JVM調用的方法

接口中聲明的所有變量本身是final

final和abstract這兩個關鍵字反相關,final類不能abstract

final方法在編譯階段綁定,稱為靜态綁定(static binding)

沒在聲明時初始化final變量的稱為空白final變量(blank final variable),須在構造器中初始化,或調用this()初始化。不這麼做的話,編譯器會報錯“final變量(變量名)需要進行初始化”

final變量就是常量,而且通常常量名要大寫

private final int COUNT = 10;

對于集合對象聲明為final指的是引用不能被更改,但是你可以向其中增加,删除或者改變内容。譬如:

private final List Loans = new ArrayList();
list.add(“home loan”);  //valid
list.add("personal loan"); //valid
loans = new Vector();  //not valid