文章來源于公眾號(hào):Java之道 ,作者Hollis
異常處理對(duì)于編寫健康茁壯的Java應(yīng)用起著極其重要的作用。異常處理并不是功能性需求,在實(shí)踐中,異常處理不單單是知道語法這么簡(jiǎn)單。下面給大家展示10個(gè)最佳實(shí)踐。
線上代碼不要使用printStackTrace()
寫完代碼后請(qǐng)一定要檢查下,代碼中千萬不要有printStackTrace()
。因?yàn)?code>printStackTrace()只會(huì)在控制臺(tái)上輸出錯(cuò)誤的堆棧信息,他只適合于用來代碼調(diào)試。
真正需要記錄異常,請(qǐng)使用日志記錄。
永遠(yuǎn)不要在catch塊中吞掉異常
catch (NoSuchMethodException e) {
return null;
}
永遠(yuǎn)不要不處理異常,而是返回 null,這樣異常就會(huì)被吞掉,無法獲取到任何失敗信息,會(huì)給日后的問題排查帶來巨大困難。
在需要的地方聲明特定的受檢異常
public void foo() throws Exception { //錯(cuò)誤做法
}
一定要盡量避免上面的代碼,因?yàn)樗恼{(diào)用者完全不知道錯(cuò)誤的原因到底是什么。
在方法聲明中,可以由方法拋出一些特定受檢異常。如果有多個(gè),那就分別拋出多個(gè),這樣這個(gè)方法的使用者才會(huì)分別針對(duì)每個(gè)異常做特定的處理,從而避免發(fā)生故障。
public void foo() throws SpecificException1, SpecificException2 {
//正確做法
}
始終只捕獲那些可以處理的異常
catch (NoSuchMethodException e)
{
throw e; //這代碼一點(diǎn)用都沒有
}
這是一個(gè)基本概念,當(dāng)你能夠處理他時(shí),你再捕獲這個(gè)異常,否則永遠(yuǎn)都不要捕獲他。
如果你不能在catch
塊中處理它,那么就不要先捕獲再直接拋出,這樣沒有任何意義。
盡量捕獲特定的子類,而不是直接捕獲Exception類
try {
someMethod();
}
catch (Exception e)
{
LOGGER.error("method has failed", e);
}
以上代碼,最大的問題就是,如果someMethod()
的開發(fā)者在里面新增了一個(gè)特定的異常,并且預(yù)期是調(diào)用方能夠特殊的對(duì)他進(jìn)行處理。
但是調(diào)用者直接catch
了Exception
類,就會(huì)導(dǎo)致永遠(yuǎn)無法知道someMethod
的具體變化細(xì)節(jié)。這久可能導(dǎo)致在運(yùn)行的過程中在某一個(gè)時(shí)間點(diǎn)程序崩潰。
永遠(yuǎn)不要捕獲Throwable類
這是一個(gè)嚴(yán)重的問題,因?yàn)?Java 中的Error
也可以是Throwable
的子類。但是Error
是 Java 虛擬機(jī)本身無法控制的。Java 虛擬機(jī)甚至可能不會(huì)在出現(xiàn)任何錯(cuò)誤時(shí)請(qǐng)求用戶的catch
子句。
始終在自定義異常中覆蓋原有的異常,這樣堆棧跟蹤就不會(huì)丟失
catch (NoSuchMethodException e)
{
throw new MyServiceException("Some information: " + e.getMessage()); //錯(cuò)誤做法
}
上面的命令可能會(huì)丟失掉主異常的堆棧跟蹤。正確的方法是:
catch (NoSuchMethodException e) {
throw new MyServiceException("Some information: " , e); //正確做法
}
可以記錄異?;驋伋霎惓?,但不要同時(shí)做
catch (NoSuchMethodException e) {
LOGGER.error("Some information", e);
throw e;
}
如上面的代碼所示,拋出和日志記錄可能會(huì)在日志文件中產(chǎn)生多個(gè)日志消息。
這就會(huì)導(dǎo)致同一個(gè)問題,卻在日志中有很多不同的錯(cuò)誤信息,使得開發(fā)人員陷入混亂。
永遠(yuǎn)不要在finally中拋出異常
try {
someMethod(); //拋出 exceptionOne
}
finally
{
cleanUp(); //如果在這里再拋出一個(gè)異常,那么try中的exceptionOne將會(huì)丟失forever
}
在上面的例子中,如果someMethod()
拋出一個(gè)異常,并且在finally
塊中,cleanUp()
也拋出一個(gè)異常,那么初始的exceptionOne
(正確的錯(cuò)誤異常)將永遠(yuǎn)丟失。
如果您不打算處理異常,請(qǐng)使用finally塊而不是catch塊
try {
someMethod();
}
finally
{
cleanUp();
}
這也是一個(gè)很好的實(shí)踐。如果在你的方法中訪問其他方法,而該方法拋出了異常你不想處理,但是仍然需要做一些清理工作,那么在finally
塊中進(jìn)行清理。不要使用catch
塊。
以上就是W3Cschool編程獅
關(guān)于解決Java異常的10個(gè)實(shí)踐經(jīng)驗(yàn)的相關(guān)介紹了,希望對(duì)大家有所幫助。