對於java異常處理你是否都掌握了呢
如果是
你是否能在下面這段代碼中
迅速找出異常處理的六個問題嗎?
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
))
}
conn
close()
// ⑶
out
close()
}
catch(Exception ex) // ⑵
{
ex
printStackTrace()
//⑴
⑷
作為一個Java程序員
你至少應該能夠找出兩個問題
但是
如果你不能找出全部六個問題
請繼續閱讀本文
本文討論的不是Java異常處理的一般性原則
因為這些原則已經被大多數人熟知
我們要做的是分析各種可稱為
反例
(anti
pattern)的違背優秀編碼規范的常見壞習慣
幫助讀者熟悉這些典型的反面例子
從而能夠在實際工作中敏銳地察覺和避免這些問題
反例之一
丟棄異常
代碼
行
行
這段代碼捕獲了異常卻不作任何處理
可以算得上Java編程中的殺手
從問題出現的頻繁程度和禍害程度來看
它也許可以和C/C++程序的一個惡名遠播的問題相提並論??不檢查緩沖區是否已滿
如果你看到了這種丟棄(而不是拋出)異常的情況
可以百分之九十九地肯定代碼存在問題
這段代碼的錯誤在於
異常(幾乎)總是意味著某些事情不對勁了
或者說至少發生了某些不尋常的事情
我們不應該對程序發出的求救信號保持沉默和無動於衷
調用一下printStackTrace算不上
處理異常
不錯
調用printStackTrace對調試程序有幫助
但程序調試階段結束之後
printStackTrace就不應再在異常處理模塊中擔負主要責任了
丟棄異常的情形非常普遍
打開JDK的ThreadDeath類的文檔
可以看到下面這段說明
特別地
雖然出現ThreadDeath是一種
正常的情形
但ThreadDeath類是Error而不是Exception的子類
因為許多應用會捕獲所有的Exception然後丟棄它不再理睬
這段話的意思是
雖然ThreadDeath代表的是一種普通的問題
但鑒於許多應用會試圖捕獲所有異常然後不予以適當的處理
所以JDK把ThreadDeath定義成了Error的子類
因為Error類代表的是一般的應用不應該去捕獲的嚴重問題
可見
丟棄異常這一壞習慣是如此常見
它甚至已經影響到了Java本身的設計
那麼
應該怎樣改正呢?主要有四個選擇
處理異常
針對該異常采取一些行動
例如修正問題
提醒某個人或進行其他一些處理
要根據具體的情形確定應該采取的動作
再次說明
調用printStackTrace算不上已經
處理好了異常
重新拋出異常
處理異常的代碼在分析異常之後
認為自己不能處理它
重新拋出異常也不失為一種選擇
把該異常轉換成另一種異常
大多數情況下
這是指把一個低級的異常轉換成應用級的異常
不要捕獲異常
結論一
既然捕獲了異常
就要對它進行適當的處理
不要捕獲異常之後又把它丟棄
不予理睬
反例之二
不指定具體的異常
代碼
行
許多時候人們會被這樣一種
美妙的
想法吸引
用一個catch語句捕獲所有的異常
最常見的情形就是使用catch(Exception ex)語句
但實際上
在絕大多數情況下
這種做法不值得提倡
為什麼呢?要理解其原因
我們必須回顧一下catch語句的用途
catch語句表示我們預期會出現某種異常
而且希望能夠處理該異常
異常類的作用就是告訴Java編譯器我們想要處理的是哪一種異常
由於絕大多數異常都直接或間接從java
lang
Exception派生
catch(Exception ex)就相當於說我們想要處理幾乎所有的異常
再來看看前面的代碼例子
我們真正想要捕獲的異常是什麼呢?最明顯的一個是SQLException
這是JDBC操作中常見的異常
另一個可能的異常是IOException
因為它要操作OutputStreamWriter
顯然
在同一個catch塊中處理這兩種截然不同的異常是不合適的
如果用兩個catch塊分別捕獲SQLException和IOException就要好多了
這就是說
catch語句應當盡量指定具體的異常類型
而不應該指定涵蓋范圍太廣的Exception類
另一方面
除了這兩個特定的異常
還有其他許多異常也可能出現
例如
如果由於某種原因
executeQuery返回了null
該怎麼辦?答案是讓它們繼續拋出
即不必捕獲也不必處理
實際上
我們不能也不應該去捕獲可能出現的所有異常
程序的其他地方還有捕獲異常的機會?直至最後由JVM處理
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26354.html