前言

Java 8 引入了 Optional 類別,用來優雅地處理可能為 null 的值,避免 NullPointerException。這篇文章介紹 Optional 的基本用法與常見應用場景。

Optional 是什麼?

Optional 是值的容器,只有兩種狀態:不是有值就是沒值。將輸入的值產生為 Optional 物件,這時 Optional 物件即為該值的容器。若要取回該值,必須使用 get() 方法。

將值轉為 Optional 的方法

  • of():接受 非 null 的值 並回傳 Optional 物件
  • ofNullable():可以接受 null 的值,回傳 Optional 物件

取得 Optional 內的值的方法

  • get():如果值存在就回傳這個值,否則就丟出 NoSuchElementException
  • orElse(T other):如果值存在就回傳這個值,否則回傳 other
  • orElseGet(Supplier<? extends T> other):如果值存在就回傳這個值,否則就呼叫 other 並回傳它的結果
  • orElseThrow(Supplier<? extends X> exceptionSupplier):如果值存在就回傳這個值,否則就丟出由 exceptionSupplier 建立的例外

常用範例

Repository 可以直接用 Optional,這樣就可以避免資料庫互動時回 null 造成錯誤。

public interface DemoRepository extends JpaRepository<DemoEntity, String> {

    Optional<DemoEntity> findByGuid(String guid);
}

Service 就可以依照以下方法使用它。

@RequiredArgsConstructor
@Service
@Slf4j
public class DemoService {

    @Autowired
    private DemoRepository demoRepository;

    public GuidRs getGuidDetail(GuidRq param) {

        GuidRs guidRs = new GuidRs();

        // 利用 Optional 承接資料庫沒有這個值為 null
        var optEntity = demoRepository.findByGuid(param.getGuid());

        // 再用 isPresent() 方法判斷是否為 null
        if (optEntity.isPresent()) {

            // get() 可以取得 Optional 裡的物件
            DemoEntity temp = optEntity.get();

            guidRs.setSomething(temp.getSomething());
        }

        return guidRs;
    }
}

總結

Optional 提供了優雅的方式來處理可能為 null 的值,避免 NullPointerException。善用 Optional 可以讓程式碼更加安全且易讀。

參考資料