下面作者將介紹界中使用異常的最佳實踐(
Best Practices for Using Exceptions
)
1
.
總是要做一些清理工作(
Always clean up after yourself
)
如果你使用一些資源例如數據庫連接或者網絡連接,請記住要做一些清理工作(如
關閉數據庫連接或者網絡連接),如果你的
API
拋出
Unchecked exception
,那么你
要用
try-finally
來做必要的清理工作:
public void dataAccessCode(){
Connection conn = null;
try{
conn = getConnection();
..some code that throws SQLException
}catch(SQLException ex){
ex.printStacktrace();
} finally{
DBUtil.closeConnection(conn); } }
class DBUtil{
public static void closeConnection
(Connection conn){
try{
conn.close();
} catch(SQLException ex){
logger.error("Cannot close connection");
throw new RuntimeException(ex); } } }
DBUtil
是一個工具類來關閉
Connection.
有必要的說的使用的
finally
的重要性是不
管程序是否碰到異常,它都會被執行。在上邊的例子中,
finally
中關閉連接,如果
在關閉連接的時候出現錯誤就拋出
RuntimeException.
2
.
不要使用異常來控制流程(
Never use exceptions for flow control
)
下邊代碼中,
MaximumCountReachedException
被用于控制流程:
public void useExceptionsForFlowControl() {
try {
while (true) {
increaseCount(); }
} catch (MaximumCountReachedException ex) { }
//Continue execution }
public void increaseCount()
throws MaximumCountReachedException {
if (count >= 5000)
throw new MaximumCountReachedException(); }
上邊的
useExceptionsForFlowControl()
用一個無限循環來增加
count
直到拋出異常
,這種做法并沒有說讓代碼不易讀,但是它是程序執行效率降低。
記住,只在要會拋出異常的地方進行異常處理。
3
.
不要忽略異常
當有異常被拋出的時候,如果你不想恢復它,那么你要毫不猶豫的將其轉換為
unchecked exception
,而不是用一個空的
catch
塊或者什么也不做來忽略它,以至
于從表面來看象是什么也沒有發生一樣。
4
.
不要捕獲頂層的
Exception
unchecked exception
都是
RuntimeException
的子類,
RuntimeException
又繼承
Exception,
因此,如果單純的捕獲
Exception,
那么你同樣也捕獲了
RuntimeException,
如下代碼:
try{ ..
}catch(Exception ex){ }
一旦你寫出了上邊的代碼(注意
catch
塊是空的),它將忽略所有的異常,包括
unchecked exception.
5
.
Log exceptions just once
Logging the same exception stack trace more than once can confuse the
programmer examining the stack trace about the original source of
exception. So just log it once.
總結
這里給出了一些關于異常處理的一些最佳實踐,我并不想開始另一輪的關于
checked
exception
和
unchecked exception
的爭論。你可以根據自己的實際情況定制自己
異常處理,我堅信我們將有更好的辦法來處理我們代碼中的異常。
在此,我將感謝
Bruce Eckel, Joshua Kerievsky,
和
Somik Raha
對于寫這篇文章所
給于我的支持。
?
我的理解:
1
.盡量不要在發布的程序中使用打印調用棧的信息處理異常,因為這樣在發布的程序中根本不可見,就如同忽略處理異常一樣。而是要么將其處理,要么將其包裝后拋出,我們對于客戶端不能處理,也沒必要處理的異常通常包裝為
RuntimeExcepion
。這樣客戶程序可以選擇是否獲取其異常信息,給客戶程序一個選擇處理的機會。如:顯示到客戶端。更不要忽略異常,記住只打印調用堆棧和忽略異常是等價的,當然開發及調試的時候除外。
2
.因為異常是非常消耗資源的,所以不要使用異常做流程控制。
3
.總是優先使用
UnCheckedException
。
4
.不要自定義過多的異常類,因為
Java
的異常信息已經將這個異常描述得夠清晰了。要么使這個異常類承擔更多的責任。
5.
不要將過多的代碼寫入到一個
try
語句中,通常
try
語句只包含需要處理的代碼。
6. Checked
異常只是為了使程序員寫出更健壯的代碼而發明的。但是由于設計的失誤對于一些無法恢復,或者很難恢復的異常也作為
Checked
異常
,是一個錯誤的決定。事實證明不適用的
Checked
異常的
C++
和
C#
的異常處理機制比
Java
更成功。
7.
不要在程序中包含過多的異常處理語句,這樣會使你的語句難以理解,會使你的程序的效率變慢。只在需要的處理的地方處理異常
8.
不要把底層的異常拋給業務層,要么處理要么包裝后拋給業務層。因為業務層不關心這個。
9.
對于能處理的異常盡量處理,否則拋出。優先考慮
RuntimeExcepion
包裝。