首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java NullPointerException 實戰排查:循環邊界導致數組越界訪問 null

     編輯:程式設計綜合問答

異常堆疊

Exception in thread "main" java.lang.NullPointerException
    at PassengerFlight.postpone(PassengerFlight.java:50)
    at PassengerFlight.main(PassengerFlight.java:68)

問題代碼定位

// PassengerFlight.java:50
for (int i = 0; i <= this.getNumSold(); i++) { // 錯誤:<=
    System.out.println("Notify passenger " + passengers[i].getName() + ...);
}

根本原因

  • passengers 數組長度 = seat (構造函數 new Person[seat])。
  • numSold 記錄已售票數(有效乘客數),最大值 = seat。
  • 循環條件 i <= numSold 導致最後一次迭代 i == numSold,訪問 passengers[numSold] —— 該下標**超出有效範圍**(有效 0 ~ numSold-1),且該位置從未賦值,為 null。
  • 調用 passengers[i].getName() 觸發 NullPointerException。

修正代碼

// 修正:< 而非 <=
for (int i = 0; i < this.getNumSold(); i++) {
    System.out.println("Notify passenger " + passengers[i].getName() + " at " + passengers[i].getEmail() + ".");
}

通用排查口訣

  1. 看行號:堆疊指向具體行(此處第 50 行)。
  2. 找對象:該行調用方法/訪問字段的對象是誰(passengers[i])。
  3. 問來源:對象從哪來?(數組元素)。
  4. 查賦值:所有訪問路徑是否已賦值非 null?(sellTicket 僅賦值 0~numSold-1)。
  5. 核邊界:循環/下標是否超出已賦值範圍?(<= 導致多訪問一個 null)。

最佳實踐:防御性編程

// 1. 循環用 < 而非 <=
for (int i = 0; i < passengers.length && i < numSold; i++) { ... }

// 2. 或使用增強 for(自動避免下標錯誤)
for (Person p : passengers) {
    if (p != null) System.out.println("Notify " + p.getName() + "...");
}

// 3. 數組改用 List,尺寸動態匹配實際元素
private List passengers = new ArrayList<>();
// sellTicket 內:passengers.add(buyer);
// postpone 內:passengers.forEach(p -> notify(p));
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved