首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 函數式開發:Optional 處理空指針

     編輯:Java 相關知識

前言

NullPointerException 是 Java 開發中最常見的運行時異常。Tony Hoare 稱發明 null 為「十億美元錯誤」。Java 8 引入 java.util.Optional<T>,提供函數式風格的空值處理方案,本文深入講解核心 API、實戰模式與避坑指南。

一、Optional 核心概念

  • 容器物件,可能包含非 null 值,也可能為空(Optional.empty())。
  • 不可變、final 類,不繼承任何集合介面。
  • 靜態工廠:Optional.of(value)(值非 null)、Optional.ofNullable(value)(允許 null)、Optional.empty()。

二、關鍵 API 概覽

方法說明
isPresent()有值返回 true
ifPresent(Consumer)有值執行消費邏輯
orElse(T)有值返回值,否則返回預設值(立即求值)
orElseGet(Supplier)有值返回值,否則執行 Supplier(延遲求值)
orElseThrow(Supplier)無值拋出指定異常
map(Function)值存在時轉換,返回新 Optional
flatMap(Function)值存在時轉換為 Optional,扁平化
filter(Predicate)值存在且滿足條件保留,否則返回 empty

三、實戰模式

1. 替代巢狀 if (obj != null)

// 傳統
String city = null;
if (person != null) {
    Address addr = person.getAddress();
    if (addr != null) city = addr.getCity();
}

// Optional 鏈式
String city = Optional.ofNullable(person)
    .map(Person::getAddress)
    .map(Address::getCity)
    .orElse("Unknown");

2. 安全調用可能拋異常的方法

Optional.ofNullable(user)
    .map(User::getEmail)
    .filter(email -> email.contains("@"))
    .ifPresent(emailService::send);

3. 延遲計算預設值

// 昂貴操作僅在需要時執行
String config = Optional.ofNullable(System.getenv("MY_CONFIG"))
    .orElseGet(() -> computeDefaultConfig()); // 不會每次都算

4. 統一異常拋出

User user = userRepo.findById(id)
    .orElseThrow(() -> new BusinessException("USER_NOT_FOUND", id));

四、進階:結合 Stream 與集合

// 過濾列表中非空元素並提取屬性
List names = users.stream()
    .flatMap(user -> Optional.ofNullable(user.getName()).stream())
    .collect(Collectors.toList());

// 或 Java 9+ Optional::stream
List names = users.stream()
    .map(User::getName)
    .flatMap(Optional::stream)
    .collect(Collectors.toList());

五、最佳實踐與避坑

  1. 不要 將 Optional 用於欄位、方法參數、序列化場景(增加複雜度)。
  2. 優先 用 orElseGet 代替 orElse 避免不必要計算。
  3. 避免 opt.get() 直接取值(可能拋 NoSuchElementException),用 orElseThrow。
  4. 集合回傳 空列表優於 Optional<List>;單值查詢回傳 Optional。
  5. 效能:Optional 有微小物件分配開銷,極高頻熱路徑可考慮傳統 if-null。

六、總結

Optional 不是銀彈,但能將「可能為空」的語義顯式化,配合函數式 API 寫出更安全、可讀的代碼。核心原則:用於回傳值,不用於參數/欄位;鏈式處理,避免 get();善用 orElseGet/orElseThrow。結合 Java 8+ Stream、Lambda,構建現代化、健壯的 Java 代碼庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved