2017-05-09 34 views
0

我能夠調用迎接方法上null,我在這裏期待NPE因爲我們不能在null從語言規範JLS-15.12調用方法。方法調用工作正常 - 期待NPE

但是在這裏我得到hello world

public class Test{ 
    public static void greet() { 
     System.out.println("Hello world!"); 
    } 

    public static void main(String[] args) { 
     ((Test) null).greet(); 
    } 
} 

一些能幫助我,爲什麼我得到hello world而不是NPE

+0

這是一個'static'方法,所以你不會調用'null',因爲參考被忽略。 –

回答

1

我找到了答案,並想在這裏

份額Static方法,由表達式值引用的對象的運行時類型在確定調用哪個方法時不起作用,而且對象的身份(如果有的話)不起作用。

在這種情況下,沒有任何對象,但這沒有什麼區別。 一個靜態方法調用符合條件的表達式,但其價值是由編譯器忽視。有沒有要求值非空

+0

基本上這是一個爭論點,因爲你不應該在類的實例上調用靜態方法。應該使用樣式'Test.greet()'調用它們。如果您嘗試在實例上調用靜態方法,編譯器將生成警告。 – Michael

+0

@Michael編譯器*應該*生成警告。有些IDE沒有啓用它們。 – Killjoy1221

2

編譯器替換爲靜態調用您的來電。 如果你使用javap -v className檢查你的字節碼,你會看到它。

stack=0, locals=1, args_size=1 
     0: invokestatic #31     // Method greet:()V 
     3: return 

編譯器明白你不必要地用一種複雜的方式來調用你的方法,並將它減少到基本的靜態調用。靜態方法的意思是在靜態上下文中調用而不是在的實例上下文中,任何好的IDE都會要求您更改現有的代碼。

即使你做new Sample().greet();,編譯器也會做相同的優化。

+0

這可能是值得擴展你最後的聲明,因爲任何人調用實例的靜態方法可能不會立即明白爲什麼這是「不必要的複雜」。否則,非常好的答案。 – Michael