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

Java/JSP 開發六大常見陷阱與避坑指南:從空指針到資源洩漏

     編輯:Java 相關知識

陷阱一:System.out.println(null) 不拋異常,但後續操作會炸

String s = null;
System.out.println(s); // 輸出 "null",不拋 NPE
int len = s.length();  // 這裡拋 NullPointerException

對策:Objects.toString(obj, "")、String.valueOf(obj)、或提前判空。日誌框架 (SLF4J) 佔位符 "{}", obj 自動處理 null。

陷阱二:JSP/Servlet 參數直接調用方法不判空 → NPE 暴擊區

// 危險寫法
if (request.getParameter("username").equals("admin")) { ... }

// 安全寫法
String username = request.getParameter("username");
if ("admin".equals(username)) { ... }  // 常量在前,天然防 NPE

// 或 Java 8+
Optional.ofNullable(request.getParameter("username"))
        .filter("admin"::equals)
        .ifPresent(...);

高發場景:session.getAttribute()、request.getAttribute()、map.get(key) 直接鏈式調用。

陷阱三:用戶輸入轉數字未捕獲 NumberFormatException

// 危險
int age = Integer.parseInt(request.getParameter("age"));

// 安全
int age = 0;
try {
    age = Integer.parseInt(request.getParameter("age"));
} catch (NumberFormatException e) {
    log.warn("非法年齡參數", e);
    // 返回錯誤提示 / 使用默認值
}

工具類封裝:NumberUtils.toInt(str, defaultVal) (Apache Commons Lang)。

陷阱四:String.substring/indexOf/charAt 越界拋 StringIndexOutOfBoundsException

// 危險
String suffix = filename.substring(filename.lastIndexOf('.') + 1);

// 安全
int dot = filename.lastIndexOf('.');
String suffix = (dot > 0 && dot < filename.length() - 1) 
    ? filename.substring(dot + 1) : "";

通用策略:判空 → 判長度/索引合法 → 再切片。或用 FilenameUtils.getExtension() (Commons IO)。

陷阱五:NoClassDefFoundError ≠ ClassNotFoundException

異常原因排查方向
ClassNotFoundException運行時 Class.forName()/類載入器找不到類Classpath 缺失 JAR、拼寫錯誤
NoClassDefFoundError類文件存在,但靜態初始化失敗 或 版本不匹配 (主版本號)靜態區塊拋異常、JAR 衝突、JDK 版本不兼容

關鍵:NoClassDefFoundError 往往伴隨 ExceptionInInitializerError,查看根因 (Cause)。

陷阱六:外部資源 (連接/流/鎖) 未關閉 → 洩漏 → 系統癱瘓

// 危險:異常路徑未關閉
Connection conn = ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
// 正常關閉,但中間拋異常則洩漏

// 鐵律:try-with-resources (JDK 7+)
try (Connection conn = ds.getConnection();
     PreparedStatement ps = conn.prepareStatement(sql);
     ResultSet rs = ps.executeQuery()) {
    // 業務邏輯
} // 自動逆序關閉,異常時也保證關閉

資源類別:數據庫連接/Statement/ResultSet、文件/網絡流、鎖 (Lock)、HTTP 客戶端、線程池。

總結:防禦性編程檢查清單

  • ✅ 所有外部輸入 (參數、Header、Body、配置) 視為不可信,驗證 + 清洗
  • ✅ 所有方法返回值、Map/集合取值、對象屬性訪問,判空後再用
  • ✅ 所有數值轉換、字符串切片、數組/集合索引,邊界檢查
  • ✅ 所有實現 AutoCloseable/Closeable 的資源,強制 try-with-resources
  • ✅ 異常捕獲後:記錄完整堆棧、業務上下文、不吞沒、合理轉換/拋出
  • ✅ 靜態分析工具 (SpotBugs/Checkstyle/PMD) 接入 CI,攔截低級錯誤

這六大坑覆蓋了 80%+ 線上故障根因。把「防禦性編程」刻進肌肉記憶,比背誦設計模式更實在。

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