優雅判空

  • 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;  }

程式碼地址:這裡

參考文獻:

importnew

公眾號:java 團長

我的主頁