先了解一下null:
null既不是對象也不是一種類型,它僅是一種特殊的值,你可以將其賦予任何引用類型,你也可以將null轉化成任何類型,如:
String
str =
null
;
//
null can be assigned to String
Integer
itr =
null
;
//
you can assign null to Integer also
Double
dbl =
null
;
//
null can also be assigned to Double
String
myStr = (String)
null
;
//
null can be type cast to String
Integer
myItr = (Integer)
null
;
//
it can also be type casted to Integer
Double
myDbl = (Double)
null
;
//
yes it's possible, no error
進入正題:
下面的代碼,通過爲null的引用調用靜態方法,且並未產生異常。
public class Why {
public static void test() {
System.out.println("Passed");
}
public static void main(String[] args) {
Why NULL = null;
NULL.test();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
test() 是一個靜態方法,調用靜態方法不需要創建實例對象。靜態成員應該通過類型來訪問,上面對test()方法通常應該寫爲Why.test();Java中可以通過對象引用表達式來訪問一個靜態成員,但這樣通常會引起誤解,因爲這不是訪問靜態成員的常見形式。
hy aNull = null;
aNull.test(); // 實際開發中不要這樣寫
// 調用 Why.test(), 不會拋出 NullPointerException
- 1
- 2
- 3
當通過一個對象引用訪問靜態成員時,訪問只與所聲明的引用類型相關。即:
1. 所引用對象是否爲null無關緊要,因爲訪問靜態方法不需要實例對象。
2. 如果引用不爲null,運行時對象類型也無關緊要,因爲靜態調用不會導致動態調用分派。而是與類相關。
對於第2點的示例。
class T {
public static void p() {
System.out.println("p() in T");
}
}
class T1 extends T {
public static void p() {
System.out.println("p() in T1");
}
}
public class Main {
public static void main(String[] args) {
T t = new T1();
t.p();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
最後訪問靜態方法,建議使用標準寫法來寫,這樣不容易引起誤解,也便於走讀維護。