1. 程式人生 > >Java final、static 關鍵字

Java final、static 關鍵字

nbsp fin 嵌套 可變 運行時 空指針 含義 相關 public

問:談談 Java 中 final、finally、finalize 的區別?

答:這道題其實沒有任何意義,無非就是考察開發者有沒有區分這幾個關鍵字的含義,僅僅關聯是因為長得像而已。

final 是一個修飾符,如果一個類被聲明為 final 則其不能再派生出新的子類,所以一個類不能既被聲明為 abstract 又被聲明為 final 的;將變量或方法聲明為 final 可以保證它們在使用中不被改變(對於對象變量來說其引用不可變,即不能再指向其他的對象,但是對象的值可變),被聲明為 final 的變量必須在聲明時給定初值,而在以後的引用中只能讀取不可修改,被聲明為 final 的方法也同樣只能使用不能重載。使用 final 關鍵字如果編譯器能夠在編譯階段確定某變量的值則編譯器就會把該變量當做編譯期常量來使用,如果需要在運行時確定(譬如方法調用)則編譯器就不會優化相關代碼;將類、方法、變量聲明為 final 能夠提高性能,這樣 JVM 就有機會進行估計並進行優化;接口中的變量都是 public static final 的。

finally 用來在異常處理時提供塊來執行任何清除操作,如果拋出一個異常,則相匹配的 catch 子句就會執行,然後控制就會進入 finally 塊。

finalize 是一個方法名,Java 允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作,這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的,它是在 Object 類中定義的,因此所有的類都繼承了它,子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作,finalize() 方法在垃圾收集器刪除對象之前對這個對象調用的。

問:java 中 static、final、static final 的區別是什麽?

答:final 可以修飾屬性、方法、類、局部變量(方法中的變量),修飾屬性的初始化可以在編譯期,也可以在運行期,初始化後不能被改變;修飾的屬性表明是一個常數;修飾方法表示方法不能在子類中被重寫;修飾類表示類不能被繼承。

static 可以修飾屬性、方法、代碼段、內部類(靜態內部類或嵌套內部類),修飾屬性的初始化在編譯期(類加載的時候),初始化後可以被修改值;修飾的屬性、方法、代碼段跟該類的具體對象無關,不創建對象也能調用 static 修飾的屬性、方法等;static 不可以修飾局部變量。

static final(或者 final static)是組合修飾,static 修飾的屬性強調它們只有一個,final 修飾的屬性表明是一個常數(創建後不能被修改),static final 修飾的屬性表示一旦給值就不可修改並且可以通過類名訪問,static final 也可以修飾方法,表示該方法不能重寫,可以在不 new 對象的情況下調用。

問:下面程序的有問題嗎,結果是什麽?

class Test {

   public static String foo(){

       System.out.println("foo called.");

       return "return called.";

   }

}

 

 

public class Demo {

   public static void main(String[] args) {

       Test obj = null;

       System.out.println(obj.foo());

   }

}

答:沒有問題,運行結果如下:

foo called.

return called.

因為 jvm 內存裏有棧區、堆區,棧區主要用來存放基礎類型數據和局部變量,堆區主要存放 new 出來的對象,在堆區又有一個叫做方法區的內存區域用來存放常量、static 變量和 static 方法、還有類的信息,static 的變量和方法不依賴對象,即使對象沒有創建,在類加載的時候已經存在信息了(Test 在聲明時就被加載了),jvm 識別出是 static 方法就直接調用了在方法區內存裏的方法,沒有報空指針異常。

問:下面程序的運行結果是什麽?為什麽

public class Test {

   public static void main(String[] args) {

       String a = "hello2";

       final String b = "hello";

       String c = b + 2;

       String d = "hello";

       String e = d + 2;

       System.out.println((a == c));

       System.out.println((a == e));

   }

}

答:運行結果如下:

true

false

因為當 final 變量是基本數據類型以及 String 類型時如果在編譯期間能知道它的確切值則編譯器會把它當做編譯期常量使用,也就是說在用到該 final 變量的地方相當於直接訪問了這個常量,不需要在運行時確定,所以上面代碼中由於變量 b 被 final 修飾從而被當做編譯器常量,故在使用到 b 的地方會直接將變量 b 替換為它的值,而對於變量 d 的訪問卻需要在運行時通過鏈接來進行。

Java final、static 關鍵字