1 OutputStreamWriter out = ...
2 java.sql.Connection conn = ...
3 try { // ⑸
4 Statement stat = conn.createStatement();
5 ResultSet rs = stat.executeQuery("select uid, name from user");
6 while (rs.next()) {
7 out.println("ID:" + rs.getString("uid") // ⑹
8 + ",姓名:" + rs.getString("name"));
9 }
10 conn.close(); // ⑶
11 out.close();
12 } catch (Exception ex) { // ⑵
13 ex.printStackTrace(); // ⑴,⑷
14 }
至少能找出兩個算合格,六個全中才算精通。以下逐一剖析。
位置:第 12-14 行。捕獲異常僅列印堆疊追蹤,不做任何實質處理。這是 Java 界的「頭號殺手」,頻率與危害極高。printStackTrace() 只適合除錯階段,正式環境必須妥善處理。
四種改正方向:
throw ex; 讓上層處理。SQLException) 包裝為業務異常 (如 ApplicationException),語意更清晰。結論: 捕獲即責任,絕不可捕獲後置之不理。
位置:第 12 行 catch (Exception ex)。試圖一網打盡所有異常是誘人陷阱。實際上應針對具體異常:本例中 SQLException (JDBC) 與 IOException (I/O) 處理邏輯截然不同,必須分開捕獲。其他未預期異常應讓其繼續拋出。
結論: 盡可能指定具體異常型別,必要時多寫幾個catch區塊,切勿貪圖省事捕獲Exception。
位置:第 3-14 行。異常會打斷正常流程,若發生在 conn.close() 之前,連線與輸出流將洩漏。Java 提供 finally 保證清理碼必執行。
結論: 所有資源 (檔案、Socket、JDBC 連線) 必須在finally中正確釋放,且finally內部避免再拋出難以處理的異常。
位置:第 3-18 行。迴圈中段拋出異常時,堆疊追蹤僅顯示類別/方法,無法知曉具體是哪筆資料、哪個欄位導致錯誤。應補充上下文資訊 (當前處理的 ID、SQL 語句等),並整理堆疊追蹤為易讀格式。
結論: 異常處理模組需提供足夠診斷資訊:類別、方法、關鍵狀態變數、易讀的錯誤描述。
位置:第 3-14 行。將大量代碼塞進單一 try 如同旅行將所有物品塞進一個大箱子,出錯時難以定位具體語句。應將可能拋出異常的代碼拆分為多個小 try-catch,各自處理對應異常。
結論: 縮小 try 區塊範圍,精準對應異常來源。
位置:第 6-11 行。迴圈中段異常導致輸出中斷,下游系統收到不完整資料卻無任何警示。資料不完整損害可能超過系統停機。對策:
結論: 全面評估異常對執行流程與資料完整性的影響,預留應對機制。
OutputStreamWriter out = ...
java.sql.Connection conn = ...
try {
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select uid, name from user");
while (rs.next()) {
out.println("ID:" + rs.getString("uid") + ",姓名: " + rs.getString("name"));
}
} catch (SQLException sqlex) {
out.println("警告:資料不完整");
throw new ApplicationException("讀取資料時出現 SQL 錯誤", sqlex);
} catch (IOException ioex) {
throw new ApplicationException("寫入資料時出現 IO 錯誤", ioex);
} finally {
if (conn != null) {
try { conn.close(); }
catch (SQLException sqlex2) {
System.err(this.getClass().getName() + ".mymethod - 無法關閉資料庫連線: " + sqlex2);
}
}
if (out != null) {
try { out.close(); }
catch (IOException ioex2) {
System.err(this.getClass().getName() + ".mymethod - 無法關閉輸出檔案: " + ioex2);
}
}
}
這些不是教條,常識與經驗才是最好老師。無把握時務必加詳盡註釋。別嘲笑這些錯誤——連資深工程師也常因「圖方便」誤入歧途。它們是 Java 世界的惡魔,美麗動人、無孔不入、時刻誘惑。記住:勿以惡小而為之,勿以善小而不為。