Error 相關類型的異常是程序沒法處理(大多都是修改代碼沒法解決的)的異常,這類異常一般須要咱們調整JVM的運行環境java
Exception 相關類型的異常是程序能夠處理的異常,其包含兩大子類型code
編譯異常(CheckedException)對象
一般是語法錯誤,或是方法明確指明可能拋出異常則必須捕獲處理blog
運行時異常(RuntimeException)繼承
指的是檢查階段沒有發現任何問題,知足全部語法規範,只有在運行時才能發現的異常編譯器
關鍵字 try catch finally throws throw虛擬機
基本語法:it
注意:io
finally 表示最終,即不管異常是否真的發生了,最終都會執行finally編譯
如要打斷finally的執行能夠直接退出虛擬機,System.exit();
在方法中,若是有finally,即便在 try 或catch中遇到了return 語句,方法也不會當即結束,而是必須執行完finally後纔會執行結束,
案例:
class Test{ public static void main(String[] args){ System.out.println(func(0)); //此處獲得的結果爲10000; //若是沒有finally 則是10; } public static int func(int arg){ try{ int a = 1/arg; return a; }catch(Exception e){ return 10; }finally{ return 10000; } } }
用於方法定義,在定義方法時可使用throws來聲明,方法可能會拋出某種類型的異常
當方法中可能會有異常,可是方法自己沒法處理,或是不想處理....就可使用throws來拋出
須要強調的是:若是一個異常拋出後沒最終沒有獲得處理,將致使程序運行中斷,因此一般咱們不能聽任無論
注意:
簡單的說,只要聲明瞭,則代表方法內部不會處理該異常,誰調用就由誰處理;
一個方法也能夠聲明拋出多種不一樣類型異常,響應的調用方應增長對應的catch
案例:
package com.yh.test; public class Test { public static void main(String[] args){ //一直拋向程序入口都沒有獲得處理則程序被終止 func3(); } static public void func2() throws ArithmeticException{ int a = 1/0; } static public void func3() throws ArithmeticException{ try{ func2();//func2拋出異常 }catch (Exception e){ //沒法處理則繼續向上拋出 throw e; } } }
拋出多種類型異常:
import java.util.InputMismatchException; import java.util.Scanner; public class Test { public static void main(String[] args){ try { func3(); } catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch (InputMismatchException e) { e.printStackTrace(); } } static public int func3() throws ArrayIndexOutOfBoundsException,InputMismatchException{// try{ int a = new Scanner(System.in).nextInt(); return 10/a; } }
當方法的提供者須要調用者提供一些數據,可是這些數據不合法,致使功能沒法正常處理時,就應該主動拋出異常
調用方能夠在捕獲到異常後進行處理
方法內部致使的異常本身處理,調用者致使的異常則拋出(或者能處理則處理)
由於Exception 既包含了運行時異常 又包含了 編譯時異常,因此要求必須處理,由此可知,當throws聲明的異常爲編譯時異常時則要求必須提供處理代碼;
案例:
package com.yh.test; public class Test { public static void main(String[] args){ try { func(1); } catch (Exception e) { e.printStackTrace(); } } static void func(int a) throws Exception{ if (a < 1){ throw new Exception("參數不能小於1"); } } }
當內置異常沒法知足特色業務場景時,能夠自定義異常類,只須要繼承Exception便可
案例:
class MyException extends Exception{ public MyException() { super("固定的異常提示!"); } }
當異常提示信息固定的時候能夠像上面同樣定義構造器
當一個方法拋出的異常被調用方法捕獲,可是調用方法又拋出了新的異常時,則造成了異常鏈,
若是咱們在調用方法中直接拋出新的異常不作任何額外的操做時,原始異常信息則被丟失;
咱們有兩個方法能夠保留原始異常信息
1.實例化時使用原始異常做爲參數
2.實例化後調用initCause傳入原始異常對象
案例:
package com.yh.test; public class ExceptionLinkeTest { public static void main(String[] args) { try { func2(); } catch (Exception e) { e.printStackTrace(); } } static public void fun1() throws ArithmeticException{ int a = 1 / 0; } static public void func2() throws Exception{ try{ fun1(); }catch (ArithmeticException e){ //不保留原始異常信息 //throw new Exception("新的異常信息!"); //保留異常信息方法1 throw new Exception("新的異常信息!",e); //保留異常信息方法2 Exception newex = new Exception("新的異常信息!"); newex.initCause(e); throw newex; } } }
當咱們不作處理時,獲得的異常信息以下:
使用 方法1或方法2 來保留異常信息結果以下: