976
技術社區[雲棲]
Java異常
在我參與過的一些Java項目、或者閱讀過Java代碼中,異常的使用或多或少都有點問題,有些甚至是誤用。可能很多人都了解異常的基本知識,但是使用的時候往往過於隨意,然而這樣的隨意往往並不能造成什麼嚴重的問題,所以很多程序員,尤其是初級的程序員也就沒有在意它,於是代碼中總是會有那些讓人不舒服的異常使用代碼;另一方麵,Java異常類型中包括Checked Exception(Runtime Exception)和Unchecked Exception,這兩中異常的使用也頗具爭議。
基於上述問題,總結一下Java異常基本知識點及常見錯誤,錯漏之處歡迎批評指正。
異常的基本思想:首先是拋出異常,然後catch捕捉,但是catch得和try連用(try也可以僅和finally連用,無需catch的參與),catch捕捉的是try區中代碼拋出的異常,一個 try可以跟多個catch,每個catch捕捉一種類型的異常,不確定異常時可用異常的super類,exception。異常的捕捉順序按照catch的先後順序。
1、Java異常結構
所有的Java異常都是繼承自Throwable。Throwable分為Error和Exception兩大類,而程序員需要關注的是Exception這一部分的異常,Error不需要應用程序編程人員來使用的,按照《Java核心技術卷1》的定義:
Error類層次結構描述了Java運行時係統的內部錯誤和資源耗盡錯誤,應用程序不應該拋出這樣的錯誤。
顯然一旦這樣的錯誤出現,程序除了終止別無他法。
2、Unchecked and Checked Exception
Error和Runtime Exception合稱為Unchecked Exception,對應的另一類異常叫做Checked Exception。它們的區別在於後者編譯時會被check,Java語言要求程序員必須捕獲這樣的異常(Checked Exception)或者沿著調用棧向上拋出,即在有可能拋出異常的方法體對應的方法名後加上throws specified-exception(例如throws exception)。常見的Checked異常包括IOException,例如用戶的輸入不符合要求、程序打開一個不存在的文件等。
另一類異常,Runtime Exception(Unchecked Exception),Java官方認為這樣的異常其實是bug,這類異常應該是去解決而不是去捕獲,所以Java不要求程序員捕獲這類異常,但是程序員仍然可以去捕獲這類的異常,這類異常包括空指針、數組訪問越界等。
初學者可能會誤認為文件讀寫異常或者用戶輸入異常是RuntimeException,其實不然,這裏提醒一下。
3、自定義異常選擇:Unchecked vs Checked
自定義異常選用Unchecked還是checked類型的一直以來就充滿爭議,而且其它語言也都隻有RuntimeException,如C++。當然這些爭議隻存在於Java使用者之中,Java官方並不存在任何爭議。
因為Java語言要求程序員必須捕獲Checked Exception,於是很多程序員為了偷“不需要主動捕獲異常”這個懶(當然也有很多程序員是出於設計的原因),將所有的自定義異常都繼承自RuntimeException,這樣就可以“想捕獲就捕獲,不想捕獲就隨它去了”。
我個人的觀點是:遵循Java規範。原因有二:其一,定義Checked異常可以最大限度地借助IDE工具幫助我們規範代碼,同時規範的代碼也能告訴其他的代碼調用者這段代碼會拋出什麼樣的異常,也許有人會說,RuntimeException也可以在方法體上聲明拋出何種異常,但是這樣就不能最大限度的利用IDE或者編譯器了,人總會有疲勞的時候,能讓工具幹的事情我們就不要插手了;其二,Java使用者甚多,遵循Java規範可能是唯一能讓整個Java世界編程風格統一的方式了。
4、一個可能是Java編程史上最常見的異常使用錯誤
try {
some codes;
}catch(Exception e){// 上來就直接使用異常的super類-Exception,可能程序並不會拋出任何異常或者僅僅是一個IOException
some codes;
}
與其說是錯誤,不如說是使用不規範。(有沒有隨口而出,“我擦,我每天都是這麼用的”)
5、異常小知識
1、捕獲那些知道如何處理的異常,而將那些不知道如何處理的異常繼續向上傳遞。
2、如果這是你編程造成的問題,那就是RuntimeException,反之亦然。
3、try不一定要與catch連用,也可以隻接finally;但是try必須與catch或者finally中的一個或者全部一起使用。
4、finally塊中盡可能地不要寫return語句。
5、如果try塊中有return語句,finally塊會在try塊的return語句return之前執行(假定try能執行到return語句)。
6、catch中捕獲異常的順序應遵循子類先catch的原則。
最後更新:2017-06-27 23:32:00