面試題((A)null).fun()——java中null值的強轉

upuptop發表於2019-07-22

面試題分享

public class A {public static void fun1() {
        System.out.println("fun1");
    }

    public void fun2() {
        System.out.println("fun2");
    }

    public static void main(String[] args) {
        ((A) null).fun1();
        ((A) null).fun2();
    }
}
  • 題目:
    以上程式碼是否可以編譯通過?
    如可以通過,結果是什麼?

  • 答案:
    程式碼可以編譯通過,null 可以強制轉為任意型別,呼叫其類中的靜態方法不報異常,呼叫其類中的非靜態方法會報空指標異常

理解

執行下面程式碼列印結果為 null:
        A a = (A) null;
        System.out.println(a);

由於將 null 強轉為 A 的物件,編譯上可以通過,
但是實際值仍然為 null,非靜態方法是屬於物件的方法,
所以呼叫非靜態方法會報空指標異常


執行以下程式碼不報異常:
        A a2 = null;
        a2.fun1();


由於 fun1 是靜態方法,靜態方法數隨著類載入而載入的,
所以 java 編譯器在編譯的過程中對我們的程式碼進行的了優化,
我們通過檢視 class 檔案即可看出,這兩行程式碼改變成為了下面的樣式:

        A a2 = null;
        fun1();

原因

java 編譯器對於 使用物件呼叫類中的靜態方法進行了優化。對於 a2.fun1() 給優化為 fun1()

java 推薦使用類名直接呼叫靜態方法 , 從而減少了編譯器的工作,提高了編譯效率。

如圖:左側為 java 原始檔,右側為編譯後的 class 檔案

1.jpg

相關文章