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

Java 避免 NullPointerException 實戰技巧:防禦性程式設計指南

     編輯:Java 相關知識

NullPointerException (NPE) 是 Java 開發中最常見的執行期錯誤。因 Java 到處都是物件,且每個參考都可能為 null,掌握防禦性程式設計技巧至關重要。

核心原則:讓「確定非 null」的物件來呼叫方法

錯誤示範

public boolean isNameEqual(String paraName) {
    return paraName.equals(name); // 若 paraName 為 null → NPE
}

正確做法:用已初始化的物件呼叫


private String name = ""; // 預設空字串而非 null

public boolean isNameEqual(String paraName) {
    return name.equals(paraName); // name 永不為 null,安全
}

完整的 null 安全比較模式

當雙方都可能為 null 時:


public boolean isNameEqual(String paraName) {
    if (name != null) {
        return name.equals(paraName); // name 非 null,安全呼叫
    } else if (paraName != null) {
        return false; // name 為 null 而 paraName 非 null
    } else {
        return true; // 兩者皆為 null,視為相等(視業務邏輯而定)
    }
}

Java 7+ 可用 Objects.equals(a, b) 簡化:


import java.util.Objects;

public boolean isNameEqual(String paraName) {
    return Objects.equals(name, paraName); // 內建 null 安全比較
}

集合與陣列初始化陷阱

常見錯誤:宣告集合卻未初始化即使用


// 錯誤
public class Animator extends Applet implements Runnable {
    Vector images; // 未初始化!
    int imgNumber;
    
    public void init() {
        imgNumber = new Integer(getParameter("imgNumber")).intValue(); // 可能 NPE
        for (int x = 0; x < imgNumber; x++) {
            Image img = getImage(getDocumentBase(), "img" + (x+1) + ".jpg");
            images.addElement(img); // NPE:images 為 null
        }
    }
}

修正版


public class Animator extends Applet implements Runnable {
    Vector images = new Vector(); // 宣告即初始化
    int imgNumber = 0; // 預設值
    
    public void init() {
        String param = getParameter("imgNumber");
        if (param != null) {
            try {
                imgNumber = Integer.parseInt(param);
            } catch (NumberFormatException e) {
                imgNumber = 0; // 或記錄錯誤
            }
        }
        for (int x = 0; x < imgNumber; x++) {
            Image img = getImage(getDocumentBase(), "img" + (x+1) + ".jpg");
            if (img != null) images.addElement(img); // 額外防護
        }
    }
}

現代 Java 最佳實踐

  • 使用 Optional<T> (Java 8+) 明確表達「可能缺值」的語意
  • 參數驗證:Objects.requireNonNull(arg, "訊息") 在方法開頭快速失敗
  • 避免回傳 null:回傳空集合 Collections.emptyList()、空字串 ""、或 Optional.empty()
  • 註解輔助:@NonNull、@Nullable (JSR-305 / SpotBugs / IntelliJ) 靜態分析
  • 區域變數型別推斷 (var) 配合 final 減少可變狀態

除錯技巧

JVM 參數 -XX:+ShowCodeDetailsInExceptionMessages (Java 14+) 可在 NPE 訊息中顯示具體是哪個變數為 null:


Exception in thread "main" java.lang.NullPointerException:
    Cannot invoke "String.length()" because "name" is null
        at com.example.Demo.main(Demo.java:10)

養成「先初始化、再使用、善用工具、早期驗證」的習慣,能將 NPE 風險降至最低。

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