Think in java 學習筆記--異常處理錯誤

異常的總體結構

注意所有的異常都是trowable的子類,只有是這個類的子類異常才能被jvm拋出,一個好的程序必然是對我們的異常進行了大量的處理,使得我們程序的健壯性大大增強的。

異常的分類
1)根據錯誤程度
Error一般來說是硬件錯誤或者是JVM錯誤。無法在代碼中進行處理
Exception是異常,可以抓取并進行處理,良好的異常處理機制可以增強代碼的健壯性。
2)根據是否編譯前就能檢查出來
unchecked exception(未檢查的異常): Error 和 RuntimeException 及其子類
checked exceptions (檢查了的異常):除了未檢查的異常都是檢查了的異常

** checked exceptions**: 通常是從一個可以恢復的程序中拋出來的,并且最好能夠從這種異常中使用程序恢復。比如 FileNotFoundException, ParseException 等。檢查了的異常發生在編譯階段,必須要使用 try…catch(或者 throws )否則編譯不通過

unchecked exceptions: 通常是如果一切正常的話本不該發生的異常,但是的確發生了。發生在運行期,具有不確定性,主要是由于程序的邏輯問題所引起的。比如 ArrayIndexOutOfBoundException, ClassCastException 等。從語言本身的角度講,程序不該去 catch 這類異常,雖然能夠從諸如 RuntimeException 這樣的異常中 catch 并恢復,但是并不鼓勵終端程序員這么做,因為完全沒要必要。因為這類錯誤本身就是 bug,應該被修復,出現此類錯誤時程序就應該立即停止執行。 因此,面對 Errors 和 unchecked exceptions 應該讓程序自動終止執行,程序員不該做諸如 try/catch 這樣的事情,而是應該查明原因,修改代碼邏輯。

RuntimeException:RuntimeException體系包括錯誤的類型轉換、數組越界訪問和試圖訪問空指針等等。處理 RuntimeException 的原則是:如果出現 RuntimeException,那么一定是程序員的錯誤。例如,可以通過檢查數組下標和數組邊界來避免數組越界訪問異常。其他(IOException等等)checked 異常一般是外部錯誤,例如試圖從文件尾后讀取數據等,這并不是程序本身的錯誤,而是在應用環境中出現的外部錯誤。

當拋出異常之后,會有如下的事情發生。
1)在堆上創建異常對象。
2)當前執行路徑被終止
3)從當前環境彈出對異常對象的引用。
4)異常處理機制接管程序,
5)異常處理程序執行,將程序從錯誤的狀態中恢復,使得我們的程序可以從另一個地方繼續執行或者是繼續執行下去
捕獲異常基本模塊

/**
* 一般的關于異常的處理流程
*/
try{
//try塊,嘗試產生各種(可能產生異常的)方法的程序塊
}catch(RuntimeExceptione){
//catch 塊, 用于捕獲我們產生各種異常的程序塊,對我們的異常進行必要的處理
//注意我們這里有著不同的catch塊,但是我們這里并不是和switch一樣直接和某個case進行匹配
//而是說我們這類是依次的進行比較,進入第一個符合的catch塊,而后面的catch塊就不會再去嘗試匹配
//所以在使用的時候我們應該注意順序,從上到下范圍應該是逐漸增大的。否則如果第一個就是Catch(Exception e)
//那么后面的catch代碼都將不會執行
e.printStackTrace();
}catch(Exceptione){
e.printStackTrace();
}finally{
//finally塊  無論如何都會執行的代碼。一般用于將我們的對象恢復到安全狀態,
//比如流的關閉,比如說網絡的關閉等
//不能在這里有return語句,否則的話所有的異常都會丟失。
//還有一種異常丟失的可能性就是說我們的try塊中產生異常,然后在我們的finally塊中仍然產生了異常,這個
//時候我們的try塊中的異常就會丟失
}

異常處理和異常上拋
如果在方法或者說類的最后顯示的表明throws **Exception。這就意味著說是可能會拋出這個異常,向上拋出,自身不做處理
如果在try catch塊中進行處理的exception就是自己處理,沒有向上拋出。

/**
* 用于表示異常自身處理和異常拋出的用例,其中 FileNotFoundExceptiion是向上拋出,而IOException是自己處理
* 本方法的作用是說通過文件路徑獲得文件的內容
* @param filePath 文件的路徑
* @return  文件的內容
* @throws FileNotFoundException
*/
publicstaticStringgetFileContent(StringfilePath)throwsFileNotFoundException{
//數據的暫時存儲
Stringcontent="";
//創建輸入流對象
FileReaderfReader=newFileReader(newFile(filePath));
BufferedReaderbReader=newBufferedReader(fReader);
//將我們文件中的數據按行讀取,并對可能產生的ioException進行處理
try{
while(bReader.readLine()!=null){
content+=bReader.readLine();
}
}catch(IOExceptione){
e.printStackTrace();
}
returncontent;
}

定義屬于自己的異常

/**
* 自定義的異常類
* @author kingwen
*
*/
publicclassMyExceptionextendsException{
//構造函數:每次創建實例的時候會輸出this is myexception
publicMyException(){
System.out.println("this is myexception");
}
publicMyException(Strings){
super(s);
System.out.println("this is myexception"+s);
}
}

在我們的方法中進行拋出,注意,這里要顯示的表示我們這個類可能會拋出這個異常,然后用于讓使用這個方法的人自身通過try catch塊進行處理或者是繼續通過顯示說明來進行上拋。

publicclassInputAge{
publicstaticvoidAgeChecked(inti)throwsMyException{
if(0
System.out.println("年齡正常");
}else{
thrownewMyException("年齡不正常");
}
}
}

最后,我們調用這個方法,并通過try catch塊進行處理

/**
* 本例用于測試java異常處理
*/
publicclassDemo{
publicstaticvoidmain(String[]args){
try{
InputAge.AgeChecked(109);
}catch(MyExceptione){
System.out.println("自定義的Exception");
e.printStackTrace();
}catch(Exceptione){
System.out.println("excertion e");
e.printStackTrace();
}
}
}

這個是運行結果:
首先是先new了我們的異常對象,在構造方法的時候輸出了第一個語句
然后是在我們的catch塊中進行的處理,
最后是通過e.printStackTrace()方法將我們的方法調用順序打印了出來
(就是后面的棧軌跡)


Paste_Image.png

關于異常處理我們平時應該注意的一些代碼部分
嘗試使用try catch 嵌套塊:對于創建可能失敗,處理完之后需要釋放資源的代碼

publicstaticStringgetFileContent1(StringfilePath){
//數據的暫時存儲
Stringcontent="";
//創建輸入流對象
FileReaderfReader=null;
BufferedReaderbReader=null;
try{
fReader=newFileReader(newFile(filePath));
bReader=newBufferedReader(fReader);
//將我們文件中的數據按行讀取,并對可能產生的ioException進行處理
try{
while(bReader.readLine()!=null){
content+=bReader.readLine();
}
}catch(IOExceptione){
e.printStackTrace();
}finally{
try{
bReader.close();
}catch(IOExceptione){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}catch(FileNotFoundExceptione1){
// TODO Auto-generated catch block
e1.printStackTrace();
}finally{
try{
fReader.close();
}catch(IOExceptione){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
returncontent;
}

對于構造不可能失敗但是需要使用完釋放資源的對象使用try-finally塊
在可去除對象之后緊跟try-finally 原則:

//創建對象
MyObjectobj=newMyObject()
try{
//對于我們的obj對象進行操作
}finally{
//釋放我們的對象資源
obj.dispose();
}

最后是我目前來說覺得不怎么重要的部分
棧軌跡:printStackTrace方法所提供的信息可以通過getStackTrace來進行直接訪問。
實際上就是我們通過方法e.printStackTrace();進行依次打印的東西。
我們的方法的調用信息實際上是通過一個棧來進行保存的,后進后出,
我們通過e.printStackTrace()將棧中的數據放入到一個數組中,
其中數組中的第一個元素是調用序列的最后一個,在打印的時候我們從第一個開始打印,
所以我們看到的依次是我們報錯的地方,調用它的地方,。。。。最后是main方法
重新拋出異常
方法在catch中得到我們的異常對象的引用之后,從當前位置重新拋出

try{
//try塊
}catch(Exceptione){
e.printStackTrace();
//重新拋出這個異常,但是這個異常的信息和原來的信息是一致的,
throwe;
//重新拋出這個異常,但是異常的信息變為當前位置的信息,原來的信息丟棄
//throw e.fillInStackTrace();
}

關于異常的知識暫時的了解是這樣的,歡迎覺得文章有問題的小伙伴們找我交流。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容

  • 通俗編程——白話JAVA異常機制 - 代碼之道,編程之法 - 博客頻道 - CSDN.NEThttp://blog...
    葡萄喃喃囈語閱讀 3,189評論 0 25
  • 初識異常(Exception) 比如我們在取數組里面的某個值得時候,經常會出現定義的取值范圍超過了數組的大小,那么...
    iDaniel閱讀 1,876評論 1 2
  • 六種異常處理的陋習 你覺得自己是一個Java專家嗎?是否肯定自己已經全面掌握了Java的異常處理機制?在下面這段代...
    Executing閱讀 1,348評論 0 6
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,717評論 18 399
  • 最近慢慢找回自己的狀態,其實忙碌的工作,充實了生活,更豐富了內心。 就這樣,每天有小收獲和小進步,挺好的。 該來的...
    他說他的不說閱讀 122評論 0 0