一.什麼是異常:非正常的,不一樣尋常的,不是語法錯誤。java
生活中,醫生說你身體某個部位異常,該部位和正常相比,有點不一樣功能可能受損。c++
張三開車去上班,正常狀況下,順利到達公司程序員
非正常狀況下,車子壞了,走路去公司數據庫
異常指的 不是語法錯誤 ,語法錯誤編譯通不過,不會產生字節碼文件,根本不能運行c#
程序中:代碼出現錯誤,程序就會中止運行。數組
異常處理是衡量一門語言是否成熟的標準之一。主流的java c++ c# 都有異常處理機制。網絡
異常處理可讓程序有更好的容錯性,使代碼更健壯。jvm
傳統的c語言是沒有異常處理的,此時只能程序員經過使用方法的特定返回值來表示異常狀況,而且使用if語句來判斷正常和非正常的狀況spa
沒有異常機制存在的缺點:指針
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); }