Java的異常機制
一.什麽是異常:非正常的,不同尋常的,不是語法錯誤。
生活中,醫生說你身體某個部位異常,該部位和正常相比,有點不同功能可能受損。
張三開車去上班,正常情況下,順利到達公司
非正常情況下,車子壞了,走路去公司
異常指的 不是語法錯誤 ,語法錯誤編譯通不過,不會產生字節碼文件,根本不能運行
程序中:代碼出現錯誤,程序就會停止運行。
異常處理是衡量一門語言是否成熟的標準之一。主流的java c++ c# 都有異常處理機制。
異常處理可以讓程序有更好的容錯性,使代碼更健壯。
傳統的c語言是沒有異常處理的,此時只能程序員通過使用方法的特定返回值來表示異常情況,並且使用if語句來判斷正常和非正常的情況
沒有異常機制存在的缺點:
1.使用方法的返回值表示異常的情況有限,無法窮舉所有的異常情況
2.異常處理代碼和業務代碼混合在一起,增大的程序的復雜性
3.隨著系統規模不斷增大,程序的可維護性極低
二.異常體系
針對上述的情況,我們提出解決辦法:
1.把不同類型的異常情況描述成不同的類(稱之為異常類)
2.分離異常流程代碼和正確流程代碼
3.靈活處理異常,如果當前方法解決不了,我把異常交給別人來解決
-------
非正常情況出現後,程序會中斷
Error:表示錯誤,一般指jvm相關的不可修復的錯誤,如系統崩潰,內存溢出,JVM錯誤等,由JVM拋出,我們不用處理。
Exception:表示異常,指程序中出現不正常情況,該問題可以修復(處理異常)
常見的exception:
NullPointerExeception空指針異常
ArrayIndexOutOfBoundsExeception 數組越界異常
數字格式化出問題
二.使用try catch捕獲單個異常:
異常出現後,程序會中斷,所以必須處理異常:
1.該方法不處理,而是聲明拋出,由該方法的調用者來處理(throws)
2.在方法中使用try catch語句塊來處理異常
使用try catch捕獲單個異常,語法:
try{
編寫可能出現異常的代碼
}catch(異常類型 e){
處理異常的代碼
打印異常信息
繼續拋出異常
}
註意:try 和catch
案例
三.獲取和查看異常信息,Throwable類的方法
1.String getMessage() 獲取異常的描述信息,原因(提示給用戶的時候,就提示異常信息))
2.String toString() 獲取異常的類型和異常描述信息
3.Void printStackTrace() 打印異常的跟蹤棧信息並輸出到控制臺,不需要使用syso輸出,它包含了異常的類型,異常的原因,還包括異常出現的位置,在開發和調試階段,經常使用這個方法。
註意:現在在catch語句塊中,都寫e.printStackTrace()
四.使用try-catch捕獲多個異常:
一個catch語句,只能捕獲一種異常,如果需要捕獲多個異常,就得使用多個catch語句
try{
編寫可能出現異常的代碼
}catch(異常類型A e){
處理異常的代碼//打印異常信息//繼續拋出異常
}catch(異常類型B e){
處理異常的代碼//打印異常信息//繼續拋出異常
}
註意:
1.一個catch語句只能捕獲一種類型的異常,如果需要捕獲多種異常,就得使用多個catch語句
2.代碼在一瞬間只能出現一種類型的異常,只需要一個catch捕獲,不可能出現多個異常
案例:
五.Finally代碼塊:表示最終都會執行的代碼,無論有沒有異常
什麽時候的代碼必須最終執行:
當我們在try語句中打開了一些物理資源(磁盤文件/網絡連接/數據庫連接),我們都得在使用完之後,最紅關閉打開的資源。
finally 的兩種語法:
1.try...finally :此時沒有catch來捕獲異常,因為此時根據根據應用場景,我們會拋出異常,自己不處理
2.try...catch..finally :自身需要處理異常,最終還得關閉資源
註意:finally不能單獨使用
當只有存在try或者catch中調用退出jvm的相關方法,此時finally才不會執行,否則finally永遠會執行
System.exit(0);//退出jvm
註意:如果finally有return語句,永遠返回finally中的結果,避免該情況
六.異常的分類:根據在編譯時期還是運行時期取檢查異常?
1.編譯時期異常:checked異常,在編譯時期,就會檢查,如果沒有處理異常,則編譯失敗
2.運行時異常:runtime異常,在運行時期,檢查異常,在編譯時期,運行異常不會被編譯器檢測(不報錯)
註意:運行異常,在編譯時期,可處理,可不處理
七.拋出異常:
throw:運用於方法內部,用於給調用者返回一個異常對象,和return一樣會結束當前方法
throws:運用於方法聲明上,用於表示當前方法不處理異常,而是提醒該方法的調用者來處理異常(拋出異常)
throw語句:
運用在方法內部,拋出一個具體的異常對象
throw new 異常類型(“異常信息”):終止方法
throw
一般的,當一個方法出現不正常的情況的時候,我們不知道方法該返回什麽,此時就返回一個錯誤,在catch語句塊中繼續向上拋出異常
Return是返回一個值,throw是返回一錯誤,返回給該方法
public static int dowork(int num1,int num2){ System.out.println("beging......."); if (num2 == 0){ System.out.println("有問題"); throw new ArithmeticException("被除數不能為0"); } System.out.println("-------------------------"); try{ int a =num1/num2; System.out.println(a+"aaaa"); return a; }catch(ArithmeticException e){ e.printStackTrace(); System.out.println("出異常了"); } System.out.println("end........."); return 0; } public static void main(String[] args) { try{ int ret=dowork(10,0); System.out.println(ret); }catch(ArithmeticException e){ System.out.println(e.getMessage()); } }
Throws語句
如果每一個方法都放棄處理異常直接通過throws聲明拋出,最後異常會拋到main方法,main方法不出,繼續拋出個jvm,底層的處理機制就是打印信息跟蹤棧。
public static int dowork(int num1,int num2) throws Exception{ System.out.println("begin........."); if(num2==0){ System.out.println("有問題"); throw new Exception("被除數不能為0"); } System.out.println("----------------"); try{ int a=num1/num2; System.out.println(a+"aaaaa"); return a; }catch(ArithmeticException e){ e.printStackTrace(); System.out.println("出異常了"); } System.out.println("end........."); return 0; } public static void main(String[] args) throws Exception { dowork(10,0); }
Java的異常機制