避免Java中NullPointerException的Java技巧和最佳實踐

Java中的NullPointerException是我們最經常遇到的異常了,那我們到底應該如何在編寫代碼是防患於未然呢。下面我們就從幾個方面來入手,解決這個棘手的​問題吧。​

值得慶幸的是,通過應用一些防禦性編碼技術並遵循應用程序多個部分之間的約定,您可以在一定程度上避免Java中的NullPointerException。

順便說一下,在本文中,我們將學習一些Java的編碼技術和最佳實踐,這些技巧和最佳實踐可用於避免的Java中的空指針異常。遵循這些Java的技巧還可以最大程度地減少很多Java代碼中的 x !=NULL 檢查。

作爲經驗豐富的Java的程序員,您可能已經知道其中一些技巧,並且已經在項目中遵循了這些技巧,但是對於新手和中級 發人員來說,這可能是個不錯的學習機會。順便說一句,如果您知道其他避免Java中的NullPointerException並減少的Java中的空檢查的Java的技巧,請點擊文末閱讀原文與我們分享。

Java技巧和最佳實踐

這些都是簡單的技術,很容易遵循,但是對代碼質量和健壯性有重大影響。以我的經驗,僅第一個技巧就可以顯着提高代碼質量。如前所述,如果您知道任何其他Java技巧或最佳實踐,可以幫助減少空檢查,那麼可以通過文末閱讀原文評論本文與我們分享。

1)在已知的字符串而不是未知的對象上調用equals()和equalsIgnoreCase()方法

始終在不爲null的已知字符串上調用equals()方法。由於equals()方法的方法是對稱的,調用a.equals(b)與調用b.equals(a)是一樣的,這就是爲什麼很多程序員不注意對象a和b。如果調用者爲空,則此調用的一個副作用就是可能導致NullPointerException。

Object unknownObject = null;

//錯誤的方式 - 可能引起NullPointerException
if(unknownObject.equals("knownObject")){
   System.err.println("This may result in NullPointerException if unknownObject is null");
}

//正確的方式 - 如果unknownObject爲null避免 NullPointerException
if("knownObject".equals(unknownObject)){
    System.err.println("better coding avoided NullPointerException");
}

這是避免NullPointerException的最簡單的Java技巧或最佳實踐,但是由於equals()是一種常見方法,因此帶來了極大的改進 。

2)優先使用valueOf()而不是toString(),兩個都返回相同的結果

由於在 null對象上調用toString()會引發NullPointerException ,因此,如果我們可以通過調用valueOf()獲得相同的值, 則最好這樣做,因爲將null傳遞給valueOf()會返回“ null ”,特別是在諸如Integer ,Float ,Double 這樣的包裝類的情況下或BigDecimal 。

BigDecimal bd = getPrice();
System.out.println(String.valueOf(bd)); /不會拋出NPE
System.out.println(bd.toString()); //在main線程拋出java.lang.NullPointerException"異常

如果不確定對象是否爲null,請遵循此Java技巧。

3、使用null安全的方法和庫

有很多這樣開源庫,這些庫爲您檢查空做了大量工作。最常見的一種來自Apache Common 的StringUtils。您可以使用StringUtils.isBlank() ,ISNUMERIC() ,isWhiteSpace()和其他實用程序方法,而不必擔心NullPointerException 。

//StringUtils中的方法是空指針安全的, 它不會出現NullPointerException
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));

輸出結果:

true
true
false
false

但是,在使用庫方法之前,請不要忘記閱讀Null安全方法和類的文檔。這是另一種Java最佳實踐,不需要太多的時間,但可以帶來很大的改進。

4、避免從方法中返回null,而應返回空集合或空數組

Joshua Bloch在他的書《Effective Java》中也提到了Java最佳實踐或技巧,從這本書中你將獲得更多的Java編程技巧。在公衆號【Java知己】,後臺回覆:Effective Java,可以獲得該書籍的鏈接。

通過返回空集合或空數組,您可以確保基本調用(如size(),length())不會因NullPointerException異常而失敗。集合類提供方便的空的List, Set 和Map方法:Collections.EMPTY_LIST ,Collections.EMPTY_SET 和Collections.EMPTY_MAP ,可以相應地使用它們。這是代碼示例

public List getOrders(Customer customer){
   List result = Collections.EMPTY_LIST;
   return result;
}

同樣,您可以使用Collections.EMPTY_SET 和Collections.EMPTY_MAP 而不是返回null。

5、使用註釋@NotNull和@Nullable

在編寫方法時,可以通過使用@NotNull 和@Nullable 這樣的註釋來聲明方法是否爲null安全,從而定義有關可空性的契約。 現代的編譯器,IDE或工具可以讀取此批註並幫助您進行缺失的空檢查,或者可以通知您不必要的空檢查,這會使您的代碼混亂。

IntelliJ IDE 和FindBugs的已經支持這種註釋。這些註釋也是JSR 305的一部分,但是即使在沒有任何工具或IDE支持的情況下,此註釋本身也可以作爲文檔使用。通過查看 @NotNull 和@Nullable ,程序員自己可以決定是否檢查null。順便說一句,對於Java程序員來說,這是相對較新的最佳實踐,要花些時間才能被利用起來。

6、避免在代碼中預先的自動裝箱和拆箱

儘管存在其他缺點,例如創建臨時對象,但如果包裝類對象爲null,則自動裝箱也容易發生NullPointerException 。例如, 如果人員沒有電話號碼,則以下代碼將失敗,會NullPointerException ,而不是返回null 。

Person ram = new Person("ram");
int phone = ram.getPhone();

如果與自動裝箱和拆箱一起使用,既也會引發NullPointerException 。

7、遵守約定並定義合理的預設值

在Java的中避免NullPointerException異常的最佳方法之一就是定義初始值並遵循約定。大多數NullPointerException異常發生的原因是使用不完整的信息創建對象或未提供所有必需的依賴關係。如果您不允許創建不完整的對象並優雅地拒絕任何此類請求,則可以防止很多NullPointerException 的出現。同樣,如果 允許創建對象,則應該使用合理的替代值。例如,如果沒有id 和name ,則不能創建Employee 對象 ,但是可以具有可選的電話號碼。現在,如果員工沒有電話號碼而不是返回零,否則返回默認值,例如零,但是必須謹慎地選擇該選項,踩在某些時候檢查null很容易,而不是撥打無效號碼。一個相同的註釋,通過定義什麼可以爲空和什麼不能爲空,調用者可以做出明智的決定。選擇fast-fail還是接受null也是您需要採取並堅持一致的重要設計方法。

8、如果您使用數據庫來存儲

客戶,訂單等領域對象,則應在數據庫本身上定義空值約束。由於數據庫可以從多個來源獲取數據,因此在DB中進行空能力檢查將確保數據完整性。保持數據庫的空約束也將有助於減少_Java代碼中的空檢查_。從數據庫加載對象時,您將確定其中一部分可以爲null以及其中部分不爲null,這將最大程度地減少代碼中的的 !=null 檢查。

9、使用空對象模式

這是避免Java中的NullPointerExcpetion的另一種方法。如果某個方法返回一個對象,該對象將在調用方上執行,例如Collection.iterator()方法返回Iterator,則調用方將在該迭代器上執行遍歷。假設調用者沒有任何繼承器,則可以返回Null對象而不是null。Null對象是一個特殊的對象,在不同的其中中具有不同的含義,例如,在此處,調用hasNext()並返回false 的空Iterator 可以是null對象。類似地,對於返回容器或集合類型的方法,應使用空對象而不是返回null。我打算寫一篇關於空對象模式,在這裏我將分享Java中空對象的更多示例。

夥計們,這些都是容易理解的Java技巧和最佳實踐,可以避免NullPointerException。您將不費吹灰之力就可以知道這些技巧有多有用。如果您要使用其他任何技巧來避免此例外(不在此列表中) ),則請通過評論與我們分享,我將在此處後續更新。


“不積跬步,無以至千里”,希望未來的你能:有夢爲馬 隨處可棲!加油,少年!

關注公衆號:「Java 知己」,每天更新Java知識哦,期待你的到來!

  • 發送「Group」,與 10 萬程序員一起進步。
  • 發送「面試」,領取BATJ面試資料、面試視頻攻略。
  • 發送「玩轉算法」,領取《玩轉算法》系列視頻教程。
  • 千萬不要發送「1024」…

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章