1. 程式人生 > >打破你的認知!Java空指標居然還能這樣玩,90%人不知道…

打破你的認知!Java空指標居然還能這樣玩,90%人不知道…

相信在座的各位都遇到過空指標異常,不甚其煩,本文不是教你避免空指標,而是一些對空指標其他方面的理解。 本文可能有點另類,也可能會打破你對空指標的認知。 ## 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` 時,引發空指標錯誤。 這個在最新的《[阿里巴巴開發手冊](https://mp.weixin.qq.com/s/lQth5Ft33L_I20vEyOFAMQ)》中也提到了,連結裡面舉了三目運算子拆箱時的空指標問題,沒看過的可以點進去看,這裡就不具體展開了。獲取這份最新開發手冊,請在公眾號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)` 是有編譯錯誤提示的: ![](https://img2020.cnblogs.com/other/1218593/202008/1218593-20200806094441509-1490762037.png) 所以 `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` 不是任何物件的引用。 ## 總結 好了,今天棧長的分享就到這了,又漲姿勢了吧? 另外,之前這篇《[避免空指標的 5 個案例](https://mp.weixin.qq.com/s/cmkKuhEZl1qx6TXPxvA5pw)》也不錯的,沒看過的值得閱讀一下。 大家還知道哪些空指標的騷操作?歡迎留言分享哦!~ 最後,感謝閱讀,原創不易,各位老鐵們,給個在看、轉發下吧! **推薦去我的部落格閱讀更多:** 1.[Java JVM、集合、多執行緒、新特性系列教程](http://www.javastack.cn/categories/Java/) 2.[Spring MVC、Spring Boot、Spring Cloud 系列教程](http://www.javastack.cn/categories/Spring/) 3.[Maven、Git、Eclipse、Intellij IDEA 系列工具教程](http://www.javastack.cn/categories/工具/) 4.[Java、後端、架構、阿里巴巴等大廠最新面試題](http://www.javastack.cn/categories/面試題/) 覺得不錯,別忘了點贊+轉