[英]why doesn't this code throw NullPointerException
我剛剛與我的朋友討論了使用類名調用靜態方法,並嘗試了這個代碼並期望它在運行時拋出NPE。但事實證明它是dint。 我只是想了解執行順序。
public class One {
public static void method() {
System.out.println("in static one");
}
}
public class Two {
static One o;
public static void main(String[] args) {
o.method(); // expected NPE here, as o is null
}
}
我知道靜態方法應該用它們的類名調用,我甚至知道當我們用實例調用靜態方法時IDE會給出編譯器警告 。 但是我們也可以通過創建一個實例來調用它們,但是,我從來沒有在這里創建過實例, o
應該得到它的默認值null,因此調用o.method()
應該在運行時拋出一個NPE,但事實並非如此。 你們能否詳細說明這段代碼中的執行順序。
它的工作原理是因為重要的是o
字段的編譯時類型 。 編譯器將編譯o.method()
成相同的字節代碼作為One.method()
特別是,如果你有一個擴展One
的類Two
,並且都聲明了一個static void method()
,那么
One x = new Two();
x.method(); // calls One.method(), not Two.method()
適用於混淆目的,不太適合可維護性......
method
是靜態的,所以它不關心One
實例。
One o = null;
o.method();
是相同的:
One.method();
static
方法或變量與類定義本身相關聯,而不與類實例相關聯 。 因此你的method()
在o
上可用,但理想情況下你應該使用類名本身來調用它:
One.method();//static way of calling static methods
因為你聲明static One o;
main
功能之外。 你可以嘗試在main
函數中聲明它,它甚至無法編譯...
或者你可以在main
中將它聲明為One o = null
,然后它將被編譯,但它與One.method()
相同
如果您打算在開發環境中打開代碼,例如(Eclipse),而不是通過在這里顯示代碼來欺騙人們,而不是以斜體樣式提供靜態方法的代碼格式,那么您會看到checkstyle聲稱“不要在實例上調用靜態方法“。
所以它應該是
One.method()
代替
o.method()
然后很清楚它為什么不崩潰!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.