1.final關鍵字
我們首先來說說final。它可以用於以下四個地方:- 定義變量,包括靜態的和非靜態的。
- 定義方法的參數。
- 定義方法。
- 定義類。
依次來回顧一下每種情況下final的作用。首先來看第一種情況,如果final修飾的是一個基本類型,就表示這個變量被賦予的值是不可變的,即它是個常量;如果final修飾的是一個對象,就表示這個變量被賦予的引用是不可變的。 即不可以指向其它對象,但是該對象的內部值可以改變。類似於C++常量指針。在
總之,變量或方法參數被final修飾,就表示它只能被賦值一次,但是JAVA虛擬機爲變量設定的默認值不記作一次賦值。
被final修飾的變量必須被初始化。初始化的方式有以下幾種:final變量只能在定義時、初始化塊、類構造器初始化;靜態final變量可以在定義時、靜態初始化塊中初始化。
- public class FinalTest {
- // 在定義時初始化
- public final int A = 10;
- final int B;
- {
- B = 20;
- }
- // 靜態常量,在定義時初始化
- public static final int STATIC_D = 40;
- public static final int STATIC_E;
- // 靜態常量,在靜態初始化塊中初始化
- static {
- STATIC_E = 50;
- }
- public final int G;
- public FinalTest() {
- G = 70;
- }
- }
final變量(常量)和靜態final變量(靜態常量)未被初始化時,編譯會報錯。用final修飾的變量(常量)比非final的變量(普通變量)擁有更高的效率,因此我們在實際編程中應該儘可能多的用常量來代替普通變量,這也是一個很好的編程習慣。
當final用來定義一個方法時,表示這個方法不可以被子類重寫,但不影響子類繼承。
class ParentClass {
public final void TestFinal() {
System.out.println("父類--這是一個final方法");
}
}
public class SubClass extends ParentClass {
/**
* 子類無法重寫(override)父類的final方法,否則編譯時會報錯
*/
// public void TestFinal() {
// System.out.println("子類--重寫final方法");
// }
public static void main(String[] args) {
SubClass sc = new SubClass();
sc.TestFinal();
}
}
需要說明的是,具有private訪問權限的方法也可以增加final修飾,但是由於子類無法繼承private方法,因此也無法重寫它。編譯器在處理private方法時,是按照final方法來對待的,這樣可以提高該方法被調用時的效率。不過子類仍然可以定義同父類中的private方法具有同樣結構的方法,但是這並不會產生重寫的效果,而且它們之間也不存在必然聯繫。
最後我們再來回顧一下final用於類的情況。這個大家應該也很熟悉了,因爲我們最常用的String類就是final的。由於final類不允許被繼承,編譯器在處理時把它的所有方法都當作final的,因此final類比普通類擁有更高的效率。
抽象類含有必須由繼承自它的子類重載實現的抽象方法,因此無法同時用final和abstract來修飾同一個類。同樣的道理,final也不能用來修飾接口。
final的類的所有方法都不能被重寫,但這並不表示final的類的屬性(變量)值也是不可改變的,要想做到final類的屬性值不可改變,必須給它增加final修飾,請看下面的例子:
public final class FinalTest {
int i = 10;
public static void main(String[] args) {
FinalTest ft = new FinalTest();
ft.i = 99;
System.out.println(ft.i);
}
}
輸出99
2.finally關鍵字
finally語句只能用在try/catch語句中,並且附帶着一個語句塊,表示段語句最終總是被執行。並且,return、continue和break都沒能阻止finally語句塊的執行。任何時候,finally語句塊是在代碼塊中循環被跳過(continue)和中斷(break)之前被執行的,以及被return前執行。
倘若 return爲新建的對象。則先新建對象,繼而執行finally塊代碼,繼而返回。
3.finalize
finalize是一個方法,屬於java.lang.Object類,它的定義如下:
protected void finalize() throws Throwable { }
finalize()方法是GC(garbage collector)運行機制的一部分。 finalize()方法是在GC清理它所從屬的對象時被調用的,如果執行它的過程中拋出了無法捕獲的異常(uncaught exception),GC將終止對改對象的清理,並且該異常會被忽略;直到下一次GC開始清理這個對象時,它的finalize()會被再次調用。