天天看點

花式踩坑Java空指針和避坑的正确姿勢一、背景二、踩坑姿勢三、預防四、預發空指針五、總結

一、背景

程式員寫代碼經常被調侃為 “寫BUG”。

然而開發中遇到的其中一個主要 BUG 就是 空指針造成的。

很多人并不會認為預發空指針有多難,甚至有些人會認為自己如果寫代碼肯定會注意到。

最大的問題是,我們寫代碼時很多空指針的情況并不是直接發生的,而是被“傳遞”過來的,導緻沒有留意。

下面介紹幾種工作中可能不經意中寫出的,花式踩坑空指針異常的姿勢。

二、踩坑姿勢

2.1 自動拆箱空指針異常

如調用類似下面這種格式的二方服務接口,

花式踩坑Java空指針和避坑的正确姿勢一、背景二、踩坑姿勢三、預防四、預發空指針五、總結

如果不進行判空而直接使用,則很容易碰到空指針:

花式踩坑Java空指針和避坑的正确姿勢一、背景二、踩坑姿勢三、預防四、預發空指針五、總結

正确的使用姿勢應該是:

花式踩坑Java空指針和避坑的正确姿勢一、背景二、踩坑姿勢三、預防四、預發空指針五、總結

2.2 RPC接口傳回null

二方服務的批量查詢接口如果資料量大容易逾時,是以我們可以分批查詢,參加下面代碼:

花式踩坑Java空指針和避坑的正确姿勢一、背景二、踩坑姿勢三、預防四、預發空指針五、總結

看似沒啥問題,先将參數集合拆分成 多個小集合,然後調用傳入的接口查詢。

問題是,如果其中一批調用傳回了 null 會怎樣?

很可能發生空指針異常。

花式踩坑Java空指針和避坑的正确姿勢一、背景二、踩坑姿勢三、預防四、預發空指針五、總結

是以在合并前應該将結果為 null 的過濾掉。

三、預防

3.1 手冊

《阿裡巴巴 Java程式設計規範》 給出了空指針的一些常見場景:

傳回類型為基本資料類型,return 包裝資料類型的對象時,自動拆箱有可能産生 NPE

資料庫查詢結果可能為null

集合元素即使 isNotEmpty,取出資料元素可能為null

遠端調用傳回對象時,一律要求進行空指針判斷,防止 NPE

對于 Session 中擷取的資料,建議進行 NPE 檢查,避免空指針

級聯調用 obj.getA().getB().getC();一連串調用,易産生 NPE

3.2 源碼

Java 空指針異常的源碼注釋提供了 産生空指針的主要原因:

花式踩坑Java空指針和避坑的正确姿勢一、背景二、踩坑姿勢三、預防四、預發空指針五、總結

調用 null 對象的執行個體方法

通路或者修改 null 對象的屬性

擷取值為null 的數組長度

通路或修改值為 null 的二維數組的列

把 null 當做 Throwable 對象抛出

官方源碼列舉的幾種情況,更全面,更有參考價值。

四、預發空指針

4.1 作為接口提供方或者編寫者

編寫接口時

如果傳回值為集合類型,如果沒值盡量傳回空集合。

可以傳回Optional

4.2 作為接口的使用方

使用 commons-lang3 或者 guava的 字元串、對象、集合工具類判空

使用@Nonnull 注解等避免必傳字段前端傳null

五、總結

寫代碼時不要想當然,很多時候大意失荊州。

要了解常見的造成空指針的場景,開發時極力避免。

多看源碼注釋,會有更多發現。