第一節(jié):異常分類
示例圖
ThrowableErrorException虛擬機錯誤內(nèi)存溢出線程死鎖檢查異常非檢查異常IO異常SQL異??罩羔槷惓?shù)組下標越界算術(shù)異常類型轉(zhuǎn)換異常
補充說明
Throwable:是所有異常的父類
Error:是程序無法處理的錯誤,表示運行應(yīng)用程序中較嚴重的問題
Exception:是程序本身可以處理的異常,異常處理通常指針對Exception類型的異常
非檢查異常:程序運行時可能出現(xiàn)的異常,編譯器不要求強制處理
檢查異常:編譯器要求必須處置的異常
第二節(jié):異常處理機制
當(dāng)方法中出現(xiàn)錯誤引發(fā)的異常時,方法會創(chuàng)建異常對象并交付給運行時系統(tǒng)進行處理,當(dāng)運行時系統(tǒng)捕獲到異常時,系統(tǒng)會去尋找適合的處理器(catch塊),如果找到了與拋出異常匹配的處理器,就會執(zhí)行相關(guān)的處理邏輯;如果未找到,那么運行時系統(tǒng)將會終止運行,程序也將會終止。
第三節(jié):try-catch-finally
方案一
```publicclassDemo{
publicstaticvoidmain(String[]args) {
Scannerinput=newScanner(System.in);
try{
System.out.println("請輸入第一個整數(shù)");
intone=input.nextInt();
System.out.println("請輸入第一個整數(shù)");
inttwo=input.nextInt();
System.out.println("one/two="+(one/two));
}catch(Exceptione) {
System.out.println("程序錯誤");
e.printStackTrace();// 打印錯誤信息
}finally{
System.out.println("======運算結(jié)束======");
? ? ?? }
?? }
}
```
補充說明
try塊:用于捕獲異常
catch塊:用于處理try捕獲到的異常
finally塊:無論是否發(fā)生異常,代碼總能被執(zhí)行
異常產(chǎn)生后,try塊產(chǎn)生異常后面的代碼將不再被執(zhí)行,相對應(yīng)的catch塊中代碼將被執(zhí)行
try塊后可接零個或多個catch塊,如果沒有catch塊,則必須跟一個finally塊,catch塊必須搭配try塊使用
方案二
publicclassDemo{
publicstaticvoidmain(String[]args) {
Scannerinput=newScanner(System.in);
try{
System.out.println("請輸入第一個整數(shù)");
intone=input.nextInt();
System.out.println("請輸入第一個整數(shù)");
inttwo=input.nextInt();
System.out.println("one/two="+(one/two));
}catch(ArithmeticExceptione) {
System.out.println("除數(shù)不能為零");
e.printStackTrace();
}catch(InputMismatchExceptione) {
System.out.println("請輸入整數(shù)");
e.printStackTrace();
}catch(Exceptione) {
System.out.println("程序錯誤");
e.printStackTrace();
}finally{
System.out.println("======運算結(jié)束======");
? ? ?? }
?? }
}
補充說明
一個try塊后,不能重復(fù)捕獲相同類型異常,即catch塊中異常類型不能相同
使用多重catch塊時推薦補充一個父類異常Exception,避免匹配不到異常類型而造成程序終止
使用多重catch塊時,Exception異常建議寫在最后,使得其它異常正常執(zhí)行
特別說明
System.exit()方法可以阻止finally塊被執(zhí)行
System.exit(0)是正常退出程序,而System.exit(1)或者說非0表示非正常退出程序
方案三
publicclassDemo{
publicstaticvoidmain(String[]args) {
intresult=test();
System.out.println(result);
?? }
publicstaticinttest() {
Scannerinput=newScanner(System.in);
try{
System.out.println("請輸入第一個整數(shù)");
intone=input.nextInt();
System.out.println("請輸入第一個整數(shù)");
inttwo=input.nextInt();
returnone/two;
}catch(Exceptione) {
System.out.println("程序錯誤");
e.printStackTrace();
return0;
}finally{
System.out.println("======運算結(jié)束======");
return-1;
? ? ?? }
?? }
}
補充說明
當(dāng)try、catch中包含return語句時,程序按正常邏輯返回return結(jié)果
當(dāng)try、catch、finally 中都包含return語句時,無論程序是否出現(xiàn)異常,最終都將返回finally塊中return結(jié)果,除了return語句,其它代碼按邏輯正常執(zhí)行
強烈不建議在finally塊中添加return語句,莫得意義
第四節(jié):throws
方案一
publicclassDemo{
publicstaticvoidmain(String[]args) {
try{
intresult=test();
System.out.println(result);
}catch(ArithmeticExceptione) {
System.out.println("除數(shù)不允許為零");
e.printStackTrace();
}catch(InputMismatchExceptione) {
System.out.println("請輸入整數(shù)");
e.printStackTrace();
}catch(Exceptione) {
e.printStackTrace();
? ? ?? }
?? }
publicstaticinttest()throwsArithmeticException,InputMismatchException{
Scannerinput=newScanner(System.in);
System.out.println("請輸入第一個整數(shù)");
intone=input.nextInt();
System.out.println("請輸入第一個整數(shù)");
inttwo=input.nextInt();
System.out.println("======運算結(jié)束======");
returnone/two;
?? }
}
補充說明
異常一定要被拋出后才能被捕獲
在方法聲明處,throws聲明將要拋出的異常類型,后可接一個或多個異常類型,異常間用逗號分隔
當(dāng)throws拋出異常時,方法不會處理這些被拋出類型及其子類型的異常,而是將異常拋向此方法的調(diào)用者,由調(diào)用者來處理異常
調(diào)用者可以處理被拋出異常類型的父類異常(通常也會這樣做,避免匹配不到異常類型)
被處理的父類異常通常放在最后面
方案二
publicclassDemo{
publicstaticvoidmain(String[]args) {
try{
intresult=test();
System.out.println(result);
}catch(ArithmeticExceptione) {
System.out.println("除數(shù)不允許為零");
e.printStackTrace();
}catch(InputMismatchExceptione) {
System.out.println("請輸入整數(shù)");
e.printStackTrace();
}catch(Exceptione) {
e.printStackTrace();
? ? ?? }
?? }
publicstaticinttest()throwsException{
Scannerinput=newScanner(System.in);
System.out.println("請輸入第一個整數(shù)");
intone=input.nextInt();
System.out.println("請輸入第一個整數(shù)");
inttwo=input.nextInt();
System.out.println("======運算結(jié)束======");
returnone/two;
?? }
}
補充說明
當(dāng)throws拋出的異常類型為非檢查型異常時,調(diào)用者可以不處理(編譯可以通過),但是通常會處理該異常
當(dāng)throws拋出的異常類型為檢查型異常時,調(diào)用者必須處理該異常(編譯無法通過)
當(dāng)throws拋出的異常類型為Exception時,調(diào)用者必須處理該異常(Exception是檢查異常的父類,編譯無法通過)
第五節(jié):throw
方案一
publicclassDemo{
publicstaticvoidmain(String[]args) {
test();
?? }
publicstaticvoidtest() {
Scannerinput=newScanner(System.in);
System.out.println("請輸入年齡");
try{
intage=input.nextInt();
if(age<18) {
thrownewException("未到法定年齡");
}else{
System.out.println("歡迎學(xué)車");
? ? ? ? ?? }
}catch(Exceptione) {
e.printStackTrace();
? ? ?? }
?? }
}
補充說明
自己拋出的異常自己處理
throw拋出的是異常對象,異常對象中通常包含異常類型,異常出現(xiàn)時的程序運行時的狀態(tài)等信息
使用異常對象的構(gòu)造方法打印異常信息
throw拋出的只能是Throwable或其子類的實例對象
方案二
publicclassDemo{
publicstaticvoidmain(String[]args) {
try{
test();
}catch(Exceptione) {
e.printStackTrace();
? ? ?? }
?? }
publicstaticvoidtest()throwsException{
Scannerinput=newScanner(System.in);
System.out.println("請輸入年齡");
intage=input.nextInt();
if(age<18) {
thrownewException("未到法定年齡");
}else{
System.out.println("歡迎學(xué)車");
? ? ?? }
?? }
}
補充說明
在throw拋出異常對象的方法聲明處通過throws關(guān)鍵字聲明異常類型,由調(diào)用者處理異常(調(diào)用者可以捕獲處理或者繼續(xù)往上拋)
throws關(guān)鍵字聲明的異常類型只能是被拋出異常對象的類型或其父類類型
throw若拋出的異常對象為非檢查異常對象,調(diào)用者可以不做任何處理,其它情況下必須處理
throw通常拋出的是未檢查異常對象
第六節(jié):自定義異常
第七節(jié):異常鏈