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

Java 空指針異常全景分析:成因、場景與三大防禦策略

     編輯:Java 程式設計入門

為何基本型別不會 NPE?

int、double、boolean 等基本型別有預設值(0、false),編譯器強制初始化,故不會出現 NullPointerException。NPE 專屬於物件參考。

三大高發場景與修正

場景一:直接對可能為 null 的物件呼叫方法

// JSP/Servlet 常見錯誤
out.println(request.getParameter("username")); // 若無此參數 → null → NPE

// 修正:防禦性檢查
String name = request.getParameter("username");
if (name != null) out.println(name);
else out.println("訪客");

場景二:對 null 物件呼叫 equals/toString 等方法

String user = request.getParameter("username");
if (user.equals("root")) { ... } // user 為 null → NPE

// 修正:常量在前,或用 Objects.equals
if ("root".equals(user)) { ... }           // 安全
if (Objects.equals(user, "root")) { ... }  // JDK 7+ 推薦

場景三:鏈式呼叫中間環節為 null

String uname = session.getAttribute("user").toString(); // session 或 attribute 可能 null

// 修正:逐層驗證或 Optional 鏈
User u = (User) session.getAttribute("user");
String uname = (u != null) ? u.getName() : "匿名";

// JDK 8+ Optional 風格
String uname = Optional.ofNullable(session.getAttribute("user"))
                       .map(User.class::cast)
                       .map(User::getName)
                       .orElse("匿名");

統一防禦三板斧

策略代碼模式適用場景
1. 預設值兜底String s = val != null ? val : \"\";後續邏輯可容忍空字串
2. 早期返回/繼續if (obj == null) return;無法處理時直接跳出
3. 明確拋出業務異常if (obj == null) throw new BizException(\"資料不存在\");需讓上層感知並處理

進階預防技巧

  • @NonNull 註解:配合 Lombok @NonNull、IntelliJ 靜態分析、SpotBugs 靜態掃描
  • 建構子/Setter 驗證:Objects.requireNonNull(arg, \"參數不可為空\")
  • Optional 表達「可能缺失」:回傳型別用 Optional<T> 強迫呼叫端處理
  • 集合回傳空集合而非 null:return list != null ? list : Collections.emptyList();

除錯技巧

JVM 參數 -XX:+ShowCodeDetailsInExceptionMessages(JDK 14+)可精確指出是哪個呼叫鏈環節為 null:

Exception in thread "main" java.lang.NullPointerException:
    Cannot invoke "User.getName()" because "u" is null
        at Main.main(Main.java:10)

養成「防禦性程式設計」習慣,NPE 將不再是專案頭號殺手。

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