Java8的Optional:如何幹掉空指標?

天喬巴夏丶發表於2021-01-04

Optional概述

Optional 是個容器:它可以儲存型別T的value,或者僅僅儲存null。Optional提供很多有用的方法,這樣我們就不用顯式進行空值檢測,很好地解決了空指標異常處理的問題,比如可以使用isPresent()方法判斷value是否為null,使用get()方法獲取value值等等。

Optional的構造方法是私有的,例項不能new,可以使用靜態方法來建立:

// 1、建立一個包裝物件值為空的Optional物件
Optional<String> optStr = Optional.empty();
// 2、建立包裝物件值非空的Optional物件
Optional<String> optStr1 = Optional.of("optional");
// 3、建立包裝物件值允許為空的Optional物件
Optional<String> optStr2 = Optional.ofNullable(null);

Optional簡單案例

看完Optional的概述,我們用一個簡單的例子說明一下:

下面這段程式碼接收一個User物件,如果user為null,則丟擲異常【這是一個非常常規的避免空指標異常的做法,如果沒有這步,getName會NPE】,否則返回user的name。

    public String getName1(User user) {
        if (user == null) {
            throw new RuntimeException("user不能為null!");
        }
        return user.getName();
    }

如果使用Optional,應該怎麼去處理呢?

    public String getName2(User user) {
        return Optional.ofNullable(user) // 包裝user物件,如果user為null,則返回空的Optional物件
                .map(User::getName)
                .orElseThrow(() -> new RuntimeException("user不能為null"));// 如果有值則返回,沒有則丟擲異常。
    }
  • Optional使用靜態的ofNullable方法將user物件進行包裝,將可能為null的user物件保護起來。
    public static <T> Optional<T> ofNullable(T value) {
        // empty() 方法 建立一個空的Optional物件, of物件在構造Optional的時候,value如果weinull,會引發NPE
        return value == null ? empty() : of(value);
    }
    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        // 如果有值,直接返回值
        if (value != null) {
            return value;
        } else {
            // 丟擲異常,這個異常Supplier介面定義
            throw exceptionSupplier.get();
        }
    }

Optional的主要方法

方法 描述
empty 返回一個空的 Optional 例項
filter 如果值存在並且滿足提供的斷言, 就返回包含該值的 Optional 物件;否則返回一個空的 Optional 物件
map 如果值存在,就對該值執行提供的 mapping 函式呼叫
flatMap 如果值存在,就對該值執行提供的 mapping 函式呼叫,返回一個 Optional 型別的值,否則就返 回一個空的 Optional 物件
get 如果該值存在,將該值用 Optional 封裝返回,否則丟擲一個 NoSuchElementException 異常
ifPresent 如果值存在,就執行使用該值的方法呼叫,否則什麼也不做
isPresent 如果值存在就返回 true,否則返回 false
of 將指定值用 Optional 封裝之後返回,如果該值為 null,則丟擲一個 NullPointerException 異常
ofNullable 將指定值用 Optional 封裝之後返回,如果該值為 null,則返回一個空的 Optional 物件
orElse 如果有值則將其返回,否則返回一個預設值
orElseGet 如果有值則將其返回,否則返回一個由指定的 Supplier 介面生成的值
orElseThrow 如果有值則將其返回,否則丟擲一個由指定的 Supplier 介面生成的異常

參考閱讀

相關文章