優雅判空
- 2019 年 10 月 5 日
- 筆記
版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/qq_37933685/article/details/86094814
Java技巧系列( 一 )優雅判空
為什麼要判空
null是Java中一個很重要的概念。null設計初衷是為了表示一些缺失的東西,例如缺失的用戶、資源或其他東西。
Tony Hoare 自己說過:
我將1965年發明的 null 稱作我百萬美元的錯誤。那個時候,我正在設計第一個面向對象語言(ALGOLW)中的引用的綜合類型系統。我的目標是確保所有引用的使用都絕對安全,由編譯器自動執行檢查確保安全。但我無法抵擋放入空引用的誘惑,僅僅因為這個很容易實現。這個決定導致了不計其數的錯誤、漏洞和系統崩潰,在其後的四十年可能已經造成了百萬美元的損失。
什麼需要判空
有兩種情況會出現判空語句:
- null返回值按找約定是正常的返回值
- null返回值不是正常的返回值
第二種情況很簡單。可以使用assert來判斷或者是允許程式報錯(即拋NullPointerException)。斷言是一個被充分利用的Java特性,在1.4版本中加入了這個特性。
第一種情況就要難解釋一點了。如果你對你調用的程式碼沒有控制權的話,你就慘了。如果null返回值是正常的話,那你就必須去檢查它了。
如果可以控制你調用程式碼(當然常常還是有控制權的),那就是另一回事兒了。還是盡量的不去使用null返回值。對於返回集合的方法很簡單,只需要返回空的集合就可以了,而不是null。
如何優雅判空
NULL Object 設計模式
Nullable是空對象的相關操作介面,用於確定對象是否為空,因為在空對象模式中,對象為空會被包裝成一個Object,成為Null Object,該對象會對原有對象的所有方法進行空實現…
Optional
1、Optional.ofNullable(test),如果test為空,則返回一個單例空Optional對象,如果非空則返回一個Optional包裝對象,Optional將test包裝;
2、flatMap(Test::getTest3)判斷test是否為空,如果為空,繼續返回第一步中的單例Optional對象,否則調用Test的getTest3方法;
3、flatMap(Test3::getTest2)同上調用Test3的getTest2方法;
4、map(Test2::getInfo)同flatMap類似,但是flatMap要求Test3::getTest2返回值為Optional類型,而map不需要,flatMap不會多層包裝,map返回會再次包裝Optional;
5、orElse("");獲得map中的value,不為空則直接返回value,為空則返回傳入的參數作為默認值。
簡單的demo
Main.java
public class MainTest { @Test public void testNPE(){ Father father = new Father(); father.getChildrenOne().getAge(); } @Test public void testOptional(){ Father father=null; //簡介版 System.out.println(Optional.ofNullable(father).map(Father::getChildrenOne).orElse(null)); //分解版 Optional<Father> father1 = Optional.ofNullable(father); System.out.println(father1); Optional<ChildrenOne> childrenOne = father1.map(Father::getChildrenOne); System.out.println(childrenOne); ChildrenOne x = childrenOne.orElse(new ChildrenOne()); System.out.println(x); //判斷option包裝的類是否為空 Optional<Object> empty = Optional.empty(); } }
Father.java
@Data public class Father { private int sonNum; /** * 如果sonNum > 1 則返回示例,否則 返回空; **/ ChildrenOne getChildrenOne(){ return sonNum > 1 ? new ChildrenOne() : null; } /** * 若果sonNum >2 則返回示例, 否則 返回空 **/ ChildrenTwo getChildrenTwo(){ return sonNum>2 ? new ChildrenTwo() : null; } }
ChildrenOne.java
@Data public class ChildrenOne { private Integer age=100; public ChildrenOne(Integer age) { this.age = age; } public ChildrenOne() { } }
ChildrenTwo.java
@Data public class ChildrenTwo { private Integer age=100; }
程式碼地址:這裡
參考文獻:
公眾號:java 團長