下面這段代碼可否正常執行java
public class DemoCalc { public static void main(String[] args) { int a=0; int b=0; int c=a/b; System.out.println("運算結果爲:"+c); } }
結果是咱們在控制檯中看到一段錯誤提示,那是由於除數不能爲0。異常就是在程序運行過程當中發生的不正常事件,會中斷運行的程序。程序員
Java 使用了異常處理機制爲程序提供了錯誤處理的能力,在程序中預先設置好對付異常的處理辦法,待程序發生異常時對異常進行處理,處理完畢後,程序即可以繼續運行。數組
下面來看一下Java中是如何進行異常處理的調試
Java 的異常處理是經過5個關鍵字實現的:try、catch、finally、throw、throwscode
關鍵字 | 做用 |
---|---|
try | 執行可能產生異常的代碼 |
catch | 捕獲異常 |
finally | 不管是否發生異常,代碼總能執行 |
throws | 聲明方法要拋出的異常 |
throw | 手動拋出異常 |
Throwable 是Java 中全部錯誤和異常的父類orm
Error類:Throwable的子類,僅靠程序自己沒法恢復的嚴重的錯誤。對象
Exception類:Throwable的子類,由Java應用程序拋出和處理的非嚴重錯誤事件
RuntimeException類:Exception的子類,運行時異常,不要求程序必須作出處理。get
Checked異常:Exception的子類,程序必須處理該類異常。input
常見異常類型
異常類型 | 說明 |
---|---|
Exception | 異常層次結構的父類 |
ArithmeticException | 算數錯誤情形,如以零做除數 |
ArrayIndexOutOfBoundsException | 數組下標越界 |
NullPointerException | 嘗試訪問null對象成員 |
ClassNotFoundException | 不能加載所需的類 |
IllegalArgumentException | 方法接收到非法參數 |
ClassCastException | 對象強制類型轉換出錯 |
NumberFormatException | 數字格式轉換異常,如把"abc"轉換成數字 |
語法:
public void method(){ try{ //代碼段1 //可能產生異常的代碼段 //代碼段2 }catch(異常類型 ex){ //對異常進行處理的代碼段 } //代碼段 }
try-catch塊捕獲異常有三種狀況:
一、try塊中沒有任何異常,try中正常,catch不會執行,正常執行try-catch後的代碼。
二、try塊中可能發生異常的代碼段發生異常,代碼段2不會執行,而是執行catch中異常處理的代碼,正常執行try-catch後的代碼。
catch中異常類型的printStackTrace() 方法能進行堆棧跟蹤顯示出程序運行到當前類的執行流程,異常堆棧信息中包含了異常的類型及異常出現的位置。
三、異常類型不匹配,程序將中斷。好比try產生的異常爲ArithmeticException,catch卻用了 ClassCastException。
在控制檯中接收數字作除法運算
import java.util.Scanner; public class DemoInput { public static void main(String[] args) { Scanner input=new Scanner(System.in); try{ System.out.println("請輸入被除數(整數):"); int a=input.nextInt(); System.out.println("請輸入除數(整數):"); int b=input.nextInt(); int c=a/b; System.out.println("結果:"+c); }catch(Exception ex) { ex.printStackTrace(); } System.out.println("程序結束"); } }
語法:
public void method(){ try{ //可能會發生異常的代碼 }catch(異常類型 ex){ //異常處理 }finally{ //不管如何都要執行的代碼 } }
finally塊:是否發生異常都執行
finllay塊不執行的惟一狀況:以前的代碼中執行了 System.exit(1); 退出虛擬機
try-catch-finally的使用
import java.io.FileNotFoundException; import java.util.Scanner; public class DemoInput { public static void main(String[] args) { Scanner input=new Scanner(System.in); try{ System.out.println("請輸入被除數(整數):"); int a=input.nextInt(); System.out.println("請輸入除數(整數):"); int b=input.nextInt(); int c=a/b; System.out.println("結果:"+c); }catch(Exception ex) { ex.printStackTrace(); }finally { System.out.println("感謝您的使用"); } System.out.println("程序結束"); } }
若是在try塊或catch塊中有return語句,finally是否還會執行?運行下面代碼斷點調試觀察結果。
public class TestReturn { public static void main(String[] args) { try { int a=1+1; System.out.println("try執行"); return; } catch (Exception e) { System.out.println("catch執行"); }finally { System.out.println("finally執行"); } } }
try塊或catch塊中能夠有return語句,若是有return語句會先執行finally最後再執行return。
try塊中可能會發生多種異常,若是要不一樣的異常進行不一樣的處理,須要使用多重catch進行處理。
語法:
public void method(){ try{ //可能發生異常的代碼段 }catch(異常類型1 e){ //對異常類型1進行的處理的代碼段 }catch(異常類型2 e){ //對異常類型2進行的處理的代碼段 }catch(異常類型n e){ //對異常類型n進行的處理的代碼段 } }
當try塊中發生異常後,會逐個與catch中的異常類型進行匹配,匹配成功後,進入對應的catch進行異常處理,處理完成後再也不進入其餘catch,程序繼續執行。
排列catch語句的順序是:先子類後父類
發生異常時按順序逐個匹配
只執行第一個與異常類型匹配的catch語句
將以前的代碼 DemoInput.java 改形成多重catch
import java.io.FileNotFoundException; import java.util.InputMismatchException; import java.util.Scanner; public class DemoInput { public static void main(String[] args) { Scanner input=new Scanner(System.in); try{ System.out.println("請輸入被除數(整數):"); int a=input.nextInt(); System.out.println("請輸入除數(整數):"); int b=input.nextInt(); int c=a/b; System.out.println("結果:"+c); }catch(InputMismatchException e) { System.out.println("輸入的數有誤!"); }catch(ArithmeticException e) { System.out.println("除數不能爲0"); }catch(Exception ex) { System.out.println("發生未知異常"); }finally { System.out.println("感謝您的使用"); } System.out.println("程序結束"); } }
若是一個方法體內拋出了異常如何通知調用者,能夠在方法上聲明異常。
public class TestThrows { //聲明異常,多個異常能夠用逗號隔開 public void test()throws Exception,ClassNotFoundException{ //可能會發生異常的代碼 } }
處理方式一:調用者處理異常
public static void main(String[] args) { TestThrows t=new TestThrows(); try { t.test(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } }
處理方式二:調用者繼續聲明異常
public static void main(String[] args) throws ClassNotFoundException, Exception { TestThrows t=new TestThrows(); t.test(); }
main方法繼續聲明異常,調用者就變成虛擬機了,發生異常則按默認方式處理,打印出來。
除了系統自動拋出的異常外,有些問題須要程序員自行拋出異常
public class TestThrow { public void inputAge(int age) throws Exception { if (age<1) { throw new Exception("還有這種年齡?"); } } public static void main(String[] args) { TestThrow t=new TestThrow(); try { t.inputAge(-1); } catch (Exception e) { System.out.println("年齡有誤:"+e.getMessage()); } } }
自行拋出異常後,還須要在方法上聲明異常