網頁

2019/1/12

Java 8 Optional.of()及Optional.ofNullable的用法

Java 8的Optional.of()的用法如下。

Optional的目的是為了消除null,或是說減少程式碼中為了避免NullPointerException錯誤的if (obj == null) {...}的判斷。

當你確定一個變數在邏輯中絕對不為null時,則用Optional.of()來保證不為null。

這個變數可能是方法的輸入參數,或從某個方法取得的回傳值。若為null則會拋出NullPointerException


但如果一個變數在邏輯中可能為null,則應使用Optional.ofNullable()來允許null的情況。

public Integer getMemberNumberByType(String type) {

    // 使用Optional.of()確保輸入參數type不可為null, 並從資料庫取回資料
    List<Member> memberList = memberDao.getMemberByType(Optional.of(type).get());
    return (int) Optional.ofNullable(memberList).orElse(new ArrayList<>()).stream().count();

}

我原本搞不清楚當物件為null時,「使用Optional.of()」與「不判斷物件是否為null並直接呼叫物件」的方法都會丟出NullPointerException,那為何要多此一舉用Optional.of()? 其差別在於Optional.of()代表的是你很清楚這個物件不應該、不可能、不允許在這段邏輯中出現;相反地,如果是讓在空物件呼叫方法時才噴NullPointerException則是否意味著null是允許出現的情況?


Optional不建議作為類別屬性(class field),方法或建構子輸入參數(method or constructor input arguments)的型別,及Setter的輸入參數(setter input arguments)型別。而應該用在一個可能回傳null的方法。

例如下面getEmployeeById方法有可能因查無資料而返回null,則以Optional來返回

final String id = "001";
        service.getEmployeeById(id).ifPresent(System.out::println);
...

public Optional<Employee> getEmployeeById(String id) {
    return Optional.ofNullable(employeeDao.getEmployeeById(Optional.of(id).get()));
}

或是方法仍然返回null,但在呼叫端取回時使用Optional

final String id = "001";
Optional.ofNullable(service.getEmployeeById(id))
            .ifPresent(System.out::println);
...

public Employee getEmployeeById(String id) {
    return employeeDao.getEmployeeById(Optional.of(id).get());
}

以上的區別在於把Optioinal放在呼叫端還是在被呼叫端的回傳。

另外一個問題是,對於POJO類的getter方法,是否應該都改為以Optional<T>的型態回傳呢? 必須考慮到一些框架或函式庫在處理POJO類時會用到getter方法,若回傳Optional<T>可能發生問題。POJO還是維持其裝載值的單純特性getter不要回傳Optioinal


參考:

沒有留言:

張貼留言