1.異常的概念
在程序運行時,打斷正常程序流程的不正常情況分兩類:
1.錯誤(Error):應用程序無法捕獲的嚴重問題(自己無法處理)
例:
虛擬機相關的問題,如虛擬機崩潰、動態鏈接失敗、低層資源錯誤等
總是不受編譯器檢查的(Unchecked)
可以被拋出,但無法恢復,不可能被捕獲
2.異常(Exception):應用程序可捕獲的一般問題(自己可以處理)
例:
試圖打開的文件不存在
網絡連接中斷
數組越界
要加載的類找不到
……
異常的分類:
- Runtime異常(免檢異常)–經常出現的異常但沒必要花大量精力去處理(不可捕獲):由Runtime異常類(繼承Exception類)及其子類表示的異常,如數組越界、算術運算異常、空指針異常等。
- 必檢異常–不經常出現但影響力很大(可捕獲):除Runtime異常類及其子類之外的所有異常,如文件不存在、無效URL等。
public class TestEx {public static void main(String[] args) {int [] array = {1,2,3};//System.out.println(array[3]);//拋出異常//Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3//at java005.TestEx.main(TestEx.java:6)//可以去幫助文檔查ArrayIndexOutOfBoundsException//System.out.println(10/0);//拋出異常//Exception in thread "main" java.lang.ArithmeticException: / by zero//at java005.TestEx.main(TestEx.java:11)}
}
2.Java的異常類層次
Java.lang.Throwable是所有異常類的父類
1.檢索異常的相關信息
2.輸出顯示異常發生位置的堆棧追蹤軌跡
ArithmetcException:整數的除0操作導致的異常,如:int i=10/0;
NullPointerException:對象未實例化時,即試圖通過該對象的引用訪問其成員變量或方法,如Date d=null; System.out.println(d.toString());
IOException:輸入/輸出時可能產生的各種異常
(所有繼承Exception類的子類都以Exception結尾)
3.異常處理方法
- 捕獲并處理異常
- 將方法中產生的異常拋出
3.1捕獲并處理異常
通過try-catch-finally語句來實現,基本格式:
try{ /** 監控區域 /
//一條或多條可能拋出異常的Java語句
}catch(ExceptionType1 e1){ /* 異常處理程序 /
//捕獲到ExceptionType1類型的異常時執行的代碼
}catch (ExceptionType2 e2){ /* 異常處理程序 */
//捕獲到ExceptionType2類型的異常時執行的代碼
} …
finally{
//執行最終清理的語句
}
try-catch-finally可以實現嵌套
舉例:
try { System.out.println(10/0);System.out.println("1");System.out.println(array[3]);}catch(ArrayIndexOutOfBoundsException aioobe){System.out.println("2");}catch(ArithmeticException ae) {System.out.println("3");}finally {System.out.println("4");}System.out.println("5");
try {System.out.println(array[3]); System.out.println(10/0);System.out.println("1");}catch(ArrayIndexOutOfBoundsException aioobe){System.out.println("2");}catch(ArithmeticException ae) {System.out.println("3");}finally {System.out.println("4");}System.out.println("5");
try {System.out.println(array[3]); System.out.println(10/0);System.out.println("1");}catch(ArithmeticException ae) {System.out.println("3");}finally {System.out.println("4");}System.out.println("5");
注意:在try語句塊內,只要遇到第一個異常就會執行catch語句,剩下的不再執行,finally 語句塊可以省略,若finally語句塊存在,則無論是否發生異常均執行
package java005;public class TestEx {public static void main(String[] args) {TestEx t = new TestEx();
//28行 t.m(0);}public void m(int n) throws ArithmeticException{if(n==0) {
//32行 ArithmeticException e = new ArithmeticException("除數不能為0");throw e;//可理解為傳入到了catch(ArithmeticException ae){ae.printStackTrace();//返回堆棧路徑ae.getMassage();}}}
}
3.2多種異常同時處理
FileInputStream in = null;try {in = new FileInputStream("a.txt");int b = in.read();while(b != 1) {b = in.read();System.out.println(b);}}catch (FileNotFoundException fe) {fe.printStackTrace();}catch (IOException ioe) {//IOException是FileNotFoundException的父類,catch按照從上往下的順序運行,故子類應排在父類之前ioe.printStackTrace();}finally {try {in.close();}catch(IOException e) {e.printStackTrace();}}
封裝一下
public void readMethod(String fileName) {FileInputStream in = null;try {in = new FileInputStream(fileName);int b = in.read();while(b != 1) {b = in.read();System.out.println(b);}}catch (FileNotFoundException fe) {fe.printStackTrace();}catch (IOException ioe) {//IOException是FileNotFoundException的父類,catch按照從上往下的順序運行,故子類應排在父類之前ioe.printStackTrace();}finally {try {in.close();}catch(IOException e) {e.printStackTrace();}}}
如果不想在readMethod方法里面實現處理異常,將該異常拋出到調用該方法的程序
public void readMethod(String fileName)throws FileNotFoundException,IOException {FileInputStream in = null;in = new FileInputStream(fileName);int b = in.read();while(b != 1) {b = in.read();System.out.println(b);}}public void callRead() {try {readMethod("a.txt");}catch (FileNotFoundException fe) {fe.printStackTrace();}catch (IOException ioe) {//IOException是FileNotFoundException的父類,catch按照從上往下的順序運行,故子類應排在父類之前ioe.printStackTrace();}}
若一個異常在轉向到main()后還未被處理,則程序將非正常終止。
4.自定義異常類
public class ServerTimeOutException extends Exception{private String reason;private int port ;public ServerTimeOutException(String reason, int port){this.reason = reason;this.port = port;}public String getReason(){return reason;}public int getPort(){return port;}
}
Public void connectMe(String serverName) throws ServerTimeOutException{int success;int portToConnect = 80;success = open(serverName, portToConnect);if(success= -1){throw new ServerTimedOutException(“Couldnot connect”,80);}
}
Public void findServer(){…try{connectMe(defaultServer);} catch (ServerTimeOutException e){System.out.println(“Server timed out, try another”);}
}
4.1方法重寫拋出異常
注意:重寫方法需要拋出與原方法所拋出異常類型一致的異常或者不拋出異常。