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

Java 避免空指針異常(NPE)的現代最佳實踐

     編輯:Java 相關知識

NPE 為什麼是頭號殺手?

Tony Hoare 稱發明 null 為「十億美元錯誤」。Java 8+ 提供 Optional、Objects.requireNonNull、Stream 等工具,能從類型系統與運行時雙重防線消滅 NPE。

方案一:Optional<T> 類型系統層面消除 null

創建 Optional

// 確定非空
Optional<String> sure = Optional.of("value"); // null → NPE

// 可能為空
Optional<String> maybe = Optional.ofNullable(getName()); // null → Optional.empty()

// 明確為空
Optional<String> empty = Optional.empty();

安全消費

// 1. 函數式消費(推薦)
maybe.ifPresent(System.out::println);

// 2. 提供默認值
String val = maybe.orElse("default");           // 默認值立即計算
String val = maybe.orElseGet(() -> expensive()); // Supplier 惰性計算

// 3. 異常轉換
String val = maybe.orElseThrow(() -> new IllegalStateException("Missing!"));

// 4. 轉換鏈(避免 isPresent 判斷)
String upper = maybe.map(String::toUpperCase).orElse("DEFAULT");

方案二:Objects.requireNonNull 運行時快速失敗

public String getValSafe(Map<String, String> map, String key) {
    Map<String, String> safeMap = Objects.requireNonNull(map, "Map cannot be null");
    String safeKey = Objects.requireNonNull(key, "Key cannot be null");
    return safeMap.get(safeKey); // 後續可放心調用
}
  • 非空返回對象本身;為空拋 NullPointerException 並攜帶自定義消息。
  • 堆棧跟蹤直接定位到 requireNonNull 行,比手動 if (x == null) throw... 更乾淨。

方案三:自定義驗證器組合

public static <T> T requireNonEmpty(T obj, Predicate<T> emptyCheck, String msg) {
    Objects.requireNonNull(obj);
    Objects.requireNonNull(emptyCheck);
    if (emptyCheck.test(obj)) throw new IllegalArgumentException(msg);
    return obj;
}

// 使用示例
String s = requireNonEmpty(input, String::isEmpty, "String empty!");
List<?> list = requireNonEmpty(list, List::isEmpty, "List empty!");
User user = requireNonEmpty(user, u -> u.getName().isEmpty(), "User name empty!");

方案四:集合與 Stream 的空安全習慣

  • 返回空集合而非 null:return Collections.emptyList();
  • Stream 管道天然空安全:list.stream().filter(...).collect(toList()) 空列表返回空列表,無 NPE。
  • Map.getOrDefault / computeIfAbsent 避免雙重查找。

對比總結:何時用哪種?

場景推薦方案理由
方法返回值可能為空Optional<T>類型聲明意圖,強制調用者處理
方法參數非空前置條件Objects.requireNonNull快速失敗,堆棧清晰
業務規則驗證(非空+非空字符串等)自定義 requireNonEmpty組合驗證邏輯,復用性強
集合/Stream 管道返回空集合/空 Stream避免 null 傳播,鏈式調用無阻礙

總結

Java 8+ 工具箱已足夠強大:Optional 建模「可能缺失」,Objects.requireNonNull 守護「必須存在」,Stream 管道天然免疫空集合。拒絕 if (x != null) 滿屏飛,擁抱函數式空安全編程。

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