「Java8系列」NPE神器 Optional

「Java8系列」神祕的Lambda
「Java8系列」神奇的函數式接口
「Java8系列」流式編程Streamjava

Optional類入門

Optional<T> 類(java.util.Optional) 是一個容器類,表明一個值存在或不存在,原來用 null 表示一個值不存在,如今Optional能夠更好的表達這個概念。而且能夠避免空指針異常。你能夠把Optional對象當作一種特殊的集合數據,它至多包含一個元素。編程

經常使用方法:bash

  • Optional.of(T t) : 將指定值用 Optional 封裝以後返回,若是該值爲 null,則拋出一個 NullPointerException 異常。
  • Optional.empty() : 建立一個空的 Optional 實例。
  • Optional.ofNullable(T t) : 將指定值用 Optional 封裝以後返回,若是該值爲 null,則返回一個空的 Optional 對象。
  • get() : 若是該值存在,將該值用 Optional 封裝返回,不然拋出一個 NoSuchElementException 異常。
  • orElse(T t) : 若是調用對象包含值,返回該值,不然返回t。
  • orElseGet(Supplier s) : 若是調用對象包含值,返回該值,不然返回 s 獲取的值。
  • orElseThrow() :它會在對象爲空的時候拋出異常。
  • map(Function f) : 若是值存在,就對該值執行提供的 mapping 函數調用。
  • flatMap(Function mapper) : 若是值存在,就對該值執行提供的mapping 函數調用,返回一個 Optional 類型的值,不然就返回一個空的 Optional 對象。

注意:Optional類的設計初衷僅僅是要支持能返回Optional對象的語法,並未考慮做爲類的字段使用,也沒有實現序列化接口,在領域模型中使用Optional,有可能引起程序故障。app

使用Optional實戰

用Optional封裝可能爲null的值,咱們在項目中不少時候都會遇到,掉一個方法而後返回一個null,最後須要不斷的判空。好比獲取Map中的不含指定鍵的值,它的get方法返回的就是一個null。函數

//例如:
 Object value = map.get("key");
 
 //使用Optional封裝結果後能夠這麼寫:
 Optional<Object> value = Optional.ofNullable(map.get("key"));
 
 /**
 * 若是想在獲取爲null之後給個默認值,能夠這麼寫:
 * orElse和orElseGet的區別是當Optional的值是空值時,不管orElse仍是orElseGet都會執行;而當返回的Optional有值時,orElse會執行,而orElseGet不會執行。
 */
 Object value = Optional.ofNullable(map.get("key")).orElse("value");
 Object value1 = Optional.ofNullable(map.get("key")).orElseGet(()->"value");
複製代碼

因爲某種緣由,函數沒法返回某個值,這時除了返回null,Java API比較常見的替代作法是拋出一個異常。這種狀況比較典型的例子是使用靜態方法Integer.parseInt(String),將String轉換爲int。在這個例子中,若是String沒法解析到對應的整型,該方法就拋出一個NumberFormatException。最後的效果是,發生String沒法轉換爲int時,代碼發出一個遭遇非法參數的信號,惟一的不一樣是,此次你須要使用try/catch 語句,而不是使用if條件判斷來控制一個變量的值是否非空。工具

你也能夠用空的Optional對象,對遭遇沒法轉換的String時返回的非法值進行建模,這時你指望parseInt的返回值是一個optional。咱們沒法修改最初的Java方法,可是這無礙咱們進 行須要的改進,你能夠實現一個工具方法,將這部分邏輯封裝於其中,最終返回一個咱們但願的 Optional對象,代碼以下所示。post

public static Optional<Integer> stringToInt(String s) {
try { 
        //若是String能轉換爲對應的Integer,將其封裝在Optioal對象中返回
        return Optional.of(Integer.parseInt(s));
    } catch (NumberFormatException e) {
        //不然返回一個空的Optional對象
        return Optional.empty();
    }
}
複製代碼

Optional就是講到這裏,這個實在沒什麼好說的了,你們本身實踐吧。ui

你們看后辛苦點個贊點個關注哦!後續還會後更多的博客。有興趣能夠掃碼加羣。若有錯誤,煩請指正。 spa

相關文章
相關標籤/搜索