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

Java/JSP 開發六大高發坑點與防範指南

     編輯:Java 相關知識

1. println(null) 不拋 NPE 的隱患

String s = null;
System.out.println(s); // 輸出 "null" 字符串,不拋異常
// 後續 s.trim() → 拋 NullPointerException

對策:Objects.toString(obj, "") 或 String.valueOf(obj) 統一轉換,避免隱性 null 傳播。

2. NullPointerException (NPE) 爆發戶

高危代碼模式

// JSP/Controller 常見
if (request.getParameter("username").equals("admin")) // 參數缺失直接 NPE
out.println(session.getAttribute("user").toString())   // 屬性不存在 NPE

防範鐵律

  • 判空先行:if (param != null && param.equals("val"))
  • Objects 工具類:Objects.requireNonNull(obj, "msg")、Objects.equals(a, b) (null 安全)
  • Optional 鏈式:Optional.ofNullable(request.getParameter("p")).filter(v -> v.equals("x")).isPresent()
  • 框架層面:Spring @RequestParam(required=false)、@ModelAttribute 自動綁定。

3. NumberFormatException:用戶輸入不可信

int age = Integer.parseInt(request.getParameter("age")); // 用戶輸入 "abc" → 崩潰

標準處理模板

public static Integer parseIntSafe(String str, Integer defaultVal) {
    try {
        return (str != null && !str.trim().isEmpty()) ? Integer.parseInt(str.trim()) : defaultVal;
    } catch (NumberFormatException e) {
        log.warn("非法數字輸入: {}", str);
        return defaultVal;
    }
}

同理適用 Long、Double、BigDecimal。

4. StringIndexOutOfBoundsException:邊界未檢查

高危操作

String s = request.getParameter("code");
char c = s.charAt(5);           // s 長度 < 6 → 異常
String sub = s.substring(2, 10); // 索引越界 → 異常

安全工具方法 (建議封裝至 Util 類)

public static char charAtSafe(String s, int index, char defaultVal) {
    return (s != null && index >= 0 && index < s.length()) ? s.charAt(index) : defaultVal;
}

public static String substringSafe(String s, int begin, int end) {
    if (s == null) return "";
    begin = Math.max(0, begin);
    end = Math.min(s.length(), end);
    return (begin < end) ? s.substring(begin, end) : "";
}

5. NoClassDefFoundError:類路徑地獄

成因

  • 依賴 jar 缺失、版本衝突 (多版本共存)、類加載器隔離 (Web 容器雙親委派)。
  • 編譯時有、運行時無 (provided scope 錯誤、模組化導出缺失)。

排查步驟

  1. mvn dependency:tree / Gradle dependencies 分析衝突。
  2. 檢查 WEB-INF/lib、伺服器 lib、共享庫目錄是否重複不同版本。
  3. 啟動參數 -verbose:class 觀察類加載來源。
  4. 模組化專案檢查 module-info.java exports、opens。

6. java.lang.Error:資源洩漏導致系統崩潰

典型場景

  • 資料庫連線、輸入流、輸出流、Socket、線程池、**未在 finally/try-with-resources 中關閉**。
  • 長時間持有鎖、大對象緩存無淘汰策略、ThreadLocal 未 remove() 導致類加載器無法卸載 (PermGen/Metaspace OOM)。

資源管理鐵律

  1. 獲取即關閉:try (Resource r = acquire()) { ... } (JDBC、IO、Lock、HTTP Client 均實現 AutoCloseable)。
  2. 線程池優於手動 new Thread:ExecutorService 生命週期受控,shutdown() 优雅停機。
  3. ThreadLocal 必配 remove():try { threadLocal.set(val); ... } finally { threadLocal.remove(); }。
  4. 監控指標:連線池使用率、檔案描述符數、線程數、GC 頻率、堆外記憶體。

總結:防錯清單

檢查點工具/習慣
所有外部輸入參數判空 + 類型轉換安全封裝
所有字符串索引操作長度檢查或安全工具方法
所有資源獲取點try-with-resources / AutoCloseable
所有依賴引入依賴樹分析、版本鎖定、BOM 管理
所有 ThreadLocal 使用finally remove()

將這六類坑點內化為肌肉記憶,代碼穩健性將質的飛躍。

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