java提供了異常處理機制:程序運行受阻時候的處理方式。
1、異常分類
Error:系統錯誤,由java虛擬機拋出,很少發生;免檢異常
RuntimeException:程序設計錯誤,通常由java虛擬機拋出;免檢異常
Exception的其它異常:必檢異常,通過try-catch或者throws申明拋出
2、聲明異常:在方法聲明中使用throws聲明異常
public void method() throwsClassNotFoundException{//...
}
注意:子類重寫了父類的方法,子類的方法拋出的異常必須在被覆蓋的父類的方法中聲明中,否則不滿足java的多態使用,會報錯。
3、拋出異常:在方法內部使用throw拋出異常,在方法上必須先聲明異常
packagecom.yichang;public classMain {public static voidmain(String[] args) {try{
method1();
}catch(Exception e){
e.printStackTrace();
}
}public static void method1() throwsException{try{
method2();
}catch(Exception e) {throw e;
//throw new Exception("method1 exception", e);或者 throw new Exception(e);
//throw throw (Exception)e.fillInStackTrace();
}
}public static void method2() throwsException{throw new Exception("method2 exception");
}
}
可以拋出新建的異常,如上throw new Exception("method2 exception");
重新拋出異常
重新拋出異常--拋出當前捕獲的異常,如上method1的throw e;
java.lang.Exception: method2 exception
at com.yichang.Main.method2(Main.java:24)
at com.yichang.Main.method1(Main.java:17)
at com.yichang.Main.main(Main.java:8)
重新拋出異常--拋出鏈式異常:捕獲一個異常后拋出另一個異常,并把原始的異常信息保存下了,如上throw new Exception("method1 exception", e)
java.lang.Exception: method1 exception
at com.yichang.Main.method1(Main.java:19)
at com.yichang.Main.main(Main.java:8)
Caused by: java.lang.Exception: method2 exception
at com.yichang.Main.method2(Main.java:24)
at com.yichang.Main.method1(Main.java:17)
...1 more
或者如上throw new Exception(e)
java.lang.Exception: java.lang.Exception: method2 exception
at com.yichang.Main.method1(Main.java:19)
at com.yichang.Main.main(Main.java:8)
Caused by: java.lang.Exception: method2 exception
at com.yichang.Main.method2(Main.java:24)
at com.yichang.Main.method1(Main.java:17)
...1 more
重新拋出異常--當前拋出點為異常新的拋出點,見throw throw (Exception)e.fillInStackTrace();其中fillInStackTrace()方法返回Throwable,需強制類型轉換,以便被catch捕獲
java.lang.Exception: method2 exception
at com.yichang.Main.method1(Main.java:29)
at com.yichang.Main.main(Main.java:8)
4、捕獲異常:使用catch捕獲處理異常
try{//業務邏輯
catch(IOException){//異常處理
}catch(Exception e){//異常處理
}finally{
}
捕獲到異常e,可以使用異常API獲取詳細的信息
getMessage()
toString() 返回格式:“異常全類名:getMessage的字符串”
printStackTrace() 在控制臺打印異常調用棧信息,getStackTrace()獲取StackTraceElemen[]數組
main函數修改如下:
public static voidmain(String[] args) {try{
method1();
}catch(Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
System.out.println(e.toString());
StackTraceElement[] stackTraceElements=e.getStackTrace();for(StackTraceElement stackTraceElement: stackTraceElements) {
System.out.println(stackTraceElement.getMethodName()+" "
+stackTraceElement.getClassName()+" "
+stackTraceElement.getLineNumber());
}
}
}
輸出結果:
java.lang.Exception: method1 exception
at com.yichang.Main.method1(Main.java:27)
at com.yichang.Main.main(Main.java:8)
Caused by: java.lang.Exception: method2 exception
at com.yichang.Main.method2(Main.java:32)
at com.yichang.Main.method1(Main.java:25)
...1more
method1 exception
java.lang.Exception: method1 exception
method1 com.yichang.Main27main com.yichang.Main8
finally 與 return 、break 、continue使用時,finally也會得到執行
packagecom.yichang;public classMain {public static voidmain(String[] args) {int num=method1();
System.out.println("main方法中的num="+num);
}public static intmethod1(){int num=100;try{return ++num;
}catch(Exception e) {
e.printStackTrace();
}finally{
num--;
System.out.println("執行finally塊, 當前num="+num);
}return -1;
}
}
輸出結果:
執行finally塊, 當前num=100main方法中的num=101
異常丟失:如果在finally中有return,在try中拋出了異常,且沒有捕獲,會造成異常丟失
packagecom.yichang;public classMain {public static voidmain(String[] args) {int num=method1();
System.out.println("main方法中的num="+num);
}public static intmethod1(){try{throw new RuntimeException("異常了...");
}finally{
System.out.println("執行finally");return 1;
}
}
輸出結果:
執行finally
main方法中的num=1
5、自定義異常
通常是繼承Exception類,并使用默認構造器,最簡單的自定義異常為:
packagecom.yichang;public class MyException extendsException {
}