打破你的認知!Java空指標居然還能這樣玩,90%人不知道…
阿新 • • 發佈:2020-08-06
相信在座的各位都遇到過空指標異常,不甚其煩,本文不是教你避免空指標,而是一些對空指標其他方面的理解。
本文可能有點另類,也可能會打破你對空指標的認知。
## 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/面試題/)
覺得不錯,別忘了點贊+轉