打破你的認(rèn)知!Java空指針居然還能這樣玩,90%人不知道…

Java技術(shù)棧
www.javastack.cn
關(guān)注閱讀更多優(yōu)質(zhì)文章
相信在座的各位都遇到過空指針異常,不甚其煩,本文不是教你避免空指針,而是一些對空指針其他方面的理解。
本文可能有點另類,也可能會打破你對空指針的認(rèn)知。
1、null.method() 空指針?
我們知道調(diào)用一個對象的方法,如果對象為 null 肯定會報空指針錯誤的,但你確定一定會嗎?
不一定!
來看下面的示例:
/**
?*?訪問靜態(tài)方法
?*?@from 微信公眾號:Java技術(shù)棧
?*/
private?static?void?test()?{
????NullTest?nullTest?=?null;
????//?hello
????nullTest.test1("hello");
}
/**
?*?@from 微信公眾號:Java技術(shù)棧
?*?關(guān)注獲取更多好玩的?Java?技術(shù)干貨
?*/
private?static?void?test1(String?text)?{
????System.out.println(text);
}
如果 null 對象指向該類型的靜態(tài)方法,不但不會報空指針錯誤,而且還會運行正常,是不是很6?
因為靜態(tài)方法不屬于任何對象,它屬于類本身的,相當(dāng)于直接調(diào)用類的靜態(tài)方法。
2、拆箱空指針
是的,大家要注意拆箱引發(fā)的空指針風(fēng)險,不知道的趕緊往下看,來看下面的例子:
/**
?*?拆箱
?*?@from 微信公眾號:Java技術(shù)棧
?*/
private?static?void?test()?{
????Integer?i?=?null;
????//?//NullPointerException
????int?ii?=?i;
????System.out.println(ii);
}
拆箱如果為 null 時,引發(fā)空指針錯誤。
這個在最新的《阿里巴巴開發(fā)手冊》中也提到了,鏈接里面舉了三目運算符拆箱時的空指針問題,沒看過的可以點進(jìn)去看,這里就不具體展開了。獲取這份最新開發(fā)手冊,請在公眾號Java技術(shù)棧回復(fù)手冊。
3、運算符空指針
大家要注意了,運算符使用不當(dāng)也會引發(fā)空指針異常,來看下面的例子:
/**
?*?運算符
?*?@from 微信公眾號:Java技術(shù)棧
?*/
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?
????//NullPointerException
????System.out.println(i?&?j);
}
例子很明顯吧,使用 ==、!= 運算符比較是否相等不會有問題,但使用 > < & 等需要計算的運算符就會引起空指針異常。
4、xxx == null引發(fā)空指針?
經(jīng)常看博客或者身邊的同事說,字符串比較,常量要放前面,為了避免空指針風(fēng)險,這個對于 equals 來說確實要這樣寫。
但是,居然還有人說,甚至也有很多人也是這么在寫, == 比較,null 也要放前面,這也是為了避免空指針?還是為了避免啥風(fēng)險?
首先要搞清楚為什么有 null == xxx 這個寫法?
這個寫法的初衷是 C++ 為了避免邏輯錯誤的,因為 C++ 寫 if(xxx = NULL) 是不會報編譯錯誤的(變量賦值,永遠(yuǎn)為真),而寫 if(NULL = xxx) 是會有編譯錯誤的。
所以在 C++ 建議把 NULL 放在前面,是為了避免程序員把 == 寫成 = 引起的邏輯錯誤的。
而在 Java 里面,if(xxx = null) 是有編譯錯誤提示的:

所以 Java 中不會出現(xiàn) C++ 的沒有編譯提示而導(dǎo)致的邏輯問題,所以 Java 中的 xxx == null 和 null == xxx 是等價的,null 放前面也是沒有任何意義的。
我們甚至還可以在 Java 中寫 null == null 的判斷,這也是 OK 的,完全沒問題的。
下面是完整的示例:
/**
?*?運算符
?*?@from 微信公眾號:Java技術(shù)棧
?*/
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 會發(fā)生空指針異常么?
不會!
來看下面的示例:
/**
?*?instanceof
?*?@from 微信公眾號:Java技術(shù)棧
?*/
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 右邊可以是任意引用類型,但結(jié)果始終輸出 false,因為 null 不是任何對象的引用。
總結(jié)
好了,今天棧長的分享就到這了,又漲姿勢了吧?
另外,之前這篇《避免空指針的 5 個案例》也不錯的,沒看過的值得閱讀一下。
大家還知道哪些空指針的騷操作?歡迎留言分享哦!~
最后,感謝閱讀,原創(chuàng)不易,各位老鐵們,給個在看、轉(zhuǎn)發(fā)下吧!
關(guān)注公眾號Java技術(shù)棧回復(fù) java 可以閱讀往期干貨,后面我也會陸續(xù)分享更多好玩的 Java 技術(shù)~
點擊「閱讀原文」獲取面試題大全~
