System.out.println(str) 或 out.println(str) 當 str == null 時輸出字面量 "null",不拋 NPE。
隱患:掩蓋了對象未初始化的事實,後續調用 str.length()、str.trim() 才真正拋異常,排查困難。
防禦:關鍵業務字段顯式判空,或用 Objects.toString(obj, "") (Java 9+)/String.valueOf(obj) 安全轉換。
典型現場:
// JSP/Controller 常見
if (request.getParameter("username").equals("admin")) // 參數缺失 → null.equals → NPE
out.println(session.getAttribute("user")); // 屬性不存在 → null → println 輸出 "null" 但後續操作崩
鐵律:使用前必判空。模式:
String username = request.getParameter("username");
if (username != null && username.equals("admin")) { ... }
// 或 Java 8+ Optional
Optional.ofNullable(username).filter("admin"::equals).ifPresent(...);
場景:Integer.parseInt(request.getParameter("age")),用戶輸入 "abc" 或 "12.5"。
處理:邊界統一攔截。Controller 入口用 try-catch 捕獲,返回友好錯誤碼/頁面;或用 Spring @InitBinder + 自定義 PropertyEditor/Converter 統一轉換異常處理。
成因:substring(3,4)、charAt(5) 但字符串長度不足;或對 null 調用導致 NPE。
封裝工具類:
public class StrUtils {
public static String safeSubstring(String s, int begin, int end) {
if (s == null || begin < 0 || end > s.length() || begin >= end) return "";
return s.substring(begin, end);
}
public static char safeCharAt(String s, int index, char defaultVal) {
return (s != null && index >= 0 && index < s.length()) ? s.charAt(index) : defaultVal;
}
}
業務代碼調用工具類,集中處理邊界、空值、編碼轉換。
本質:類文件存在但運行時類加載器找不到。
排查清單:
三大成因:
治本方案:
AutoCloseable 的資源| 錯誤類型 | 核心原因 | 一行代碼防禦 |
|---|---|---|
| NPE | 未判空調用方法 | Objects.requireNonNull(obj) / Optional |
| NumberFormatException | 非法字符串轉數字 | 統一轉換器 + 異常攔截 |
| StringIndexOutOfBounds | 越界訪問字符串 | 工具類安全封裝 |
| NoClassDefFoundError | 部署缺失/類加載隔離 | Maven/Gradle 依賴管理 + 部署腳本檢查 |
| Error (資源耗盡) | 資源未關閉/洩漏 | Try-with-resources + 連接池 + 監控告警 |
好程序員不寫不出錯的代碼,而寫「出錯也能自愈、可觀測、可定位」的代碼。