反例之六:輸出數(shù)據不完整
代碼:7行-11行。
不完整的數(shù)據是Java程序的隱形殺手。仔細觀察這段代碼,考慮一下如果循環(huán)的中間拋出了異常,會發(fā)生什么事情。循環(huán)的執(zhí)行當然是要被打斷的,其次,catch塊會執(zhí)行??就這些,再也沒有其他動作了。已經輸出的數(shù)據怎么辦?使用這些數(shù)據的人或設備將收到一份不完整的(因而也是錯誤的)數(shù)據,卻得不到任何有關這份數(shù)據是否完整的提示。對于有些系統(tǒng)來說,數(shù)據不完整可能比系統(tǒng)停止運行帶來更大的損失。
較為理想的處置辦法是向輸出設備寫一些信息,聲明數(shù)據的不完整性;另一種可能有效的辦法是,先緩沖要輸出的數(shù)據,準備好全部數(shù)據之后再一次性輸出。
結論六:全面考慮可能出現(xiàn)的異常以及這些異常對執(zhí)行流程的影響。
改寫后的代碼
根據上面的討論,下面給出改寫后的代碼。也許有人會說它稍微有點?嗦,但是它有了比較完備的異常處理機制。
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("警告:數(shù)據不完整");
throw new ApplicationException("讀取數(shù)據時出現(xiàn)SQL錯誤", sqlex);
}
catch(IOException ioex)
{
throw new ApplicationException("寫入數(shù)據時出現(xiàn)IO錯誤", ioex);
}
finally
{
if (conn != null) {
try {
conn.close();
}
catch(SQLException sqlex2)
{
System.err(this.getClass().getName() + ".mymethod - 不能關閉數(shù)據庫連接: " + sqlex2.toString());
}
}
if (out != null) {
try {
out.close();
}
catch(IOException ioex2)
{
System.err(this.getClass().getName() + ".mymethod - 不能關閉輸出文件" + ioex2.toString());
}
}
}
本文的結論不是放之四海皆準的教條,有時常識和經驗才是最好的老師。如果你對自己的做法沒有百分之百的信心,務必加上詳細、全面的注釋。
另一方面,不要笑話這些錯誤,不妨問問你自己是否真地徹底擺脫了這些壞習慣。即使最有經驗的程序員偶爾也會誤入歧途,原因很簡單,因為它們確確實實帶來了“方便”。所有這些反例都可以看作Java編程世界的惡魔,它們美麗動人,無孔不入,時刻誘惑著你。也許有人會認為這些都屬于雞皮蒜毛的小事,不足掛齒,但請記。何鹨詯盒《鵀橹,勿以善小而不為。
相關推薦:計算機等考二級JAVA:Java序列化的簡單例子北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內蒙古 |