相信在座的各位都遇到過空指針異常,不甚其煩,本文不是教你避免空指針,而是一些對空指針其他方面的了解。
本文可能有點另類,也可能會打破你對空指針的認知。
1、null.method() 空指針?
我們知道調用一個對象的方法,如果對象為 null 肯定會報空指針錯誤的,但你确定一定會嗎?
不一定!
來看下面的示例:
/**
* 通路靜态方法
* @from 微信公衆号:Java技術棧
*/
private static void test() {
NullTest nullTest = null;
// hello
nullTest.test1("hello");
}
/**
* @from 微信公衆号:Java技術棧
* 關注擷取更多好玩的 Java 技術幹貨
*/
private static void test1(String text) {
System.out.println(text);
}
如果
null
對象指向該類型的靜态方法,不但不會報空指針錯誤,而且還會運作正常,是不是很6?
因為靜态方法不屬于任何對象,它屬于類本身的,相當于直接調用類的靜态方法。
2、拆箱空指針
是的,大家要注意拆箱引發的空指針風險,不知道的趕緊往下看,來看下面的例子:
/**
* 拆箱
* @from 微信公衆号:Java技術棧
*/
private static void test() {
Integer i = null;
// //NullPointerException
int ii = i;
System.out.println(ii);
}
拆箱如果為 null 時,引發空指針錯誤。
這個在最新的《阿裡巴巴開發手冊》中也提到了,連結裡面舉了三目運算符拆箱時的空指針問題,沒看過的可以點進去看,這裡就不具體展開了。擷取這份最新開發手冊,請在公衆号Java技術棧回複手冊。
3、運算符空指針
大家要注意了,運算符使用不當也會引發空指針異常,來看下面的例子:
/**
* 運算符
* @from 微信公衆号:Java技術棧
*/
private static void test5() {
Integer i = null;
Integer j = null;
// true
System.out.println(i == j);
// false
System.out.println(i != j);
// NullPointerException
System.out.println(i > j);
// NullPointerException
System.out.println(i < j);
//NullPointerException
System.out.println(i & j);
}
例子很明顯吧,使用 ==、!= 運算符比較是否相等不會有問題,但使用 > < & 等需要計算的運算符就會引起空指針異常。
4、xxx == null引發空指針?
經常看部落格或者身邊的同僚說,字元串比較,常量要放前面,為了避免空指針風險,這個對于 equals 來說确實要這樣寫。
但是,居然還有人說,甚至也有很多人也是這麼在寫, == 比較,null 也要放前面,這也是為了避免空指針?還是為了避免啥風險?
首先要搞清楚為什麼有 null == xxx 這個寫法?
這個寫法的初衷是 C++ 為了避免邏輯錯誤的,因為 C++ 寫 if(xxx = NULL) 是不會報編譯錯誤的(變量指派,永遠為真),而寫 if(NULL = xxx) 是會有編譯錯誤的。
是以在 C++ 建議把 NULL 放在前面,是為了避免程式員把 == 寫成 = 引起的邏輯錯誤的。
而在 Java 裡面,if(xxx = null) 是有編譯錯誤提示的:

是以 Java 中不會出現 C++ 的沒有編譯提示而導緻的邏輯問題,是以 Java 中的 xxx == null 和 null == xxx 是等價的,null 放前面也是沒有任何意義的。
我們甚至還可以在 Java 中寫 null == null 的判斷,這也是 OK 的,完全沒問題的。
下面是完整的示例:
/**
* 運算符
* @from 微信公衆号:Java技術棧
*/
private static void test() {
Integer i = null;
// i is null
if (null == i){
System.out.println("i is null");
}
// i is null
if (i == null){
System.out.println("i is null");
}
// i == j
Integer j = null;
if (i == j){
System.out.println("i == j");
}
// 編譯錯誤
if (i = null){
System.out.println("i is null");
}
}
有沒有小夥伴也被這個說法迷糊過?
5、null instanceof 空指針?
null instanceof 會發生空指針異常麼?
不會!
/**
* instanceof
* @from 微信公衆号:Java技術棧
*/
private static void test() {
Integer i = null;
// false
if(i instanceof Number){
System.out.println("true");
} else {
System.out.println("false");
}
// false
if(null instanceof Number){
System.out.println("true");
} else {
System.out.println("false");
}
}
如果為 null, instanceof 右邊可以是任意引用類型,但結果始終輸出 false,因為 null 不是任何對象的引用。