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

Android 日期字串解析崩潰:NullPointerException 根因與防禦性編程

     編輯:程式設計綜合問答

崩潰日誌

java.lang.NullPointerException
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1001)
    at com.cbssports.nflapp.ffb.ui.FragmentPendingTrades$PendingTradesAdapter.getView(...)

堆疊顯示在 ListView 滾動時 (AbsListView$FlingRunnable) 觸發。

問題代碼

String size = parser.getValue(e, parser.KEY_FileSizeInByte); // 實際是日期字串 "20130310"
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
try {
    Date parsed = format.parse(pendingTrade.voteDeadline); // 關鍵:voteDeadline 可能為 null
    holder.deadline.setText("Deadline | " + NEWS_DATE_FORMAT.format(parsed));
} catch (ParseException pe) {
    Log.e("ERROR", "Cannot parse: " + pendingTrade.voteDeadline);
}

根本原因

pendingTrade.voteDeadline 為 null,傳給 SimpleDateFormat.parse(null) 直接拋出 NullPointerException(而非 ParseException),導致 App 崩潰。

修正方案:防禦性非空檢查

String deadlineStr = pendingTrade.voteDeadline;
if (TextUtils.isEmpty(deadlineStr)) {
    holder.deadline.setText("Deadline | N/A");
    return;
}

SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
try {
    Date parsed = format.parse(deadlineStr);
    holder.deadline.setText("Deadline | " + NEWS_DATE_FORMAT.format(parsed));
} catch (ParseException e) {
    Log.e(TAG, "日期解析失敗: " + deadlineStr, e);
    holder.deadline.setText("Deadline | Invalid");
}

進階優化建議

  1. 緩存 SimpleDateFormat:它非執行緒安全,Adapter 中應使用 ThreadLocal 或每次新建(輕量場景可接受)
  2. 使用 java.time (API 26+):
// 現代寫法
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
try {
    LocalDate date = LocalDate.parse(deadlineStr, formatter);
    holder.deadline.setText("Deadline | " + date.format(DateTimeFormatter.ofPattern("MMM dd, yyyy")));
} catch (DateTimeParseException e) {
    // 處理異常
}
  1. 列表滾動時避免重度運算:預先在後台線程解析好日期,Adapter 只負責顯示
  2. 統一日期工具類:封裝 DateUtils.parseDeadline(String) 返回 LocalDate 或格式化後字串

避坑清單

錯誤模式後果修正
parse(null)NPE 崩潰前置非空判斷
SimpleDateFormat 為成員變數多線程共用數據錯亂/崩潰ThreadLocal / 局部新建 / java.time
catch 只捕獲 ParseException漏捕 NPEcatch (Exception) 或前置校驗
Locale 未指定某些語言環境下解析失敗Locale.US / Locale.getDefault()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved