面試題((A)null).fun()——java中null值的強轉
阿新 • • 發佈:2019-07-23
面試題分享
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 檔案