異常和錯誤的概念以及區別
- 異常的定義
- 異常是不正常的事件,不是錯誤。
- 異常是指程序運行的過程中,發生某些意外的事情,比如, 10處於0,0不能當除數,所有這樣的文件是不存在等。
- 下面我來舉個”栗子”:
- public class ExcptionTest{
public static void main(String[] args) {
System.out.println(“====運行前====”);
int a=10/0;
System.out.println(“====運行後====”);
}
}
}
- 運行結果
- Exception in thread “main” java.lang.ArithmeticException: / by zero
at com.ExcptionTest.main(ExcptionTest.java:6)
====運行前====
- Exception in thread “main” java.lang.ArithmeticException: / by zero
- 錯誤的定義
- 錯誤是很難處理的,比如內存溢出,不能夠通過異常處理來解決。
- 錯誤是很難處理的,比如內存溢出,不能夠通過異常處理來解決。
異常的體系
- Throwable類有兩個直接子類:Exception類、Error類。
- Exception表示異常,是所有異常類的父類,是程序員所關心的。
- Error表示錯誤,可能是編譯期錯誤或者系統錯誤,往往程序中並不處理。
- 請看下面的圖片瞭解它的關係
- 也就是說exception的分類:RuntimeException 和CheckedException
- 而RuntimeException也有4個子類它們分別是:
- ClassCastException
- NullPointerException
- ArrayIndexOutOfBoundsException
- ArithmeticException
- CheckedException也有2個子類:
- IOException
- SqlException
異常詳解
- RuntimeException和CheckedException的區別
- RuntimeException運行時異常,不會引起編譯錯誤,不需要強制處理。
- CheckedException會引起編譯錯誤,需要強制處理。
try-catch-finally的作用
- try : 檢測不安全的代碼塊(發現異常)
- catch: 異常處理代碼
- finally:不管出現或者不出現異常都會執行的代碼
- 其中catch和finally可以省略,但是try不能
- 可以多個catch塊
- catch的異常,父類異常的catch塊在子類異常之後
- 可以catch任何異常
- catch CheckedException時,try塊中必須存在可能引發該異常的代碼,否則編譯錯誤
- 如果catch或者finally塊中存在異常,則需要再次處理
- 下面我來舉個”栗子”:
public class Extceptions {
public static void main(String[] args) {
try{int a=10/0; //現在try存在異常,它會直接跳到catch中 System.out.println("我在try");
}catch(ArithmeticException e){
System.out.println(“我在catch”);
}finally{
//finally不管出現或者不出現異常都會執行的代碼
System.out.println(“我在final”);
}
}
}
- 輸出結果
- 我在catch
- 我在final
finally&return
- 是否 出現異常都會執行finally
- 是否在正常代碼和異常處理代碼中return,仍然會先執行finally再return
- 不會執行finally的情況:System.exit(0);
- 我來舉個”栗子”:
public class Extceptions {
public static void main(String[] args) {
try{
int b = 10/0;System.out.println("try,try"); return;
}catch(ArithmeticException e){
System.out.println("catch catch");
// System.exit(0); 這個是結束虛擬機,所有就不會運行到finally這一步了
return;
}finally{
System.out.println(“finally”);
return;}
}
}
- 輸出結果
- catch catch
- finally
層層拋出異常
- throw
- 關鍵字throw用於拋出異常
- 拋除異常後處理
- 使用try-catch捕獲異常
- 使用throws聲明異常
- 語法
- throw new 異常類構造方法;
- throw new Exception();
- throws
- 用於方法上,指出方法引發的異常。
- 可以聲明多種異常類型,用逗號分開即可。
示例
public void test throws 異常1,異常2,異常3{
}
所謂層層拋出異常
- 就是 catch中,再次用throw拋出異常
舉”栗子”
public class Throw1 {
public static void main(String[] args) {
try{
bang(130);
}catch(Exception e){
e.printStackTrace();}
}
private static void bang(int x)throws IOException{
big(x);
}
private static void big(int a)throws IOException{
if(a>120){
throw new IllegalArgumentException(“參數異常,年齡最大不超過120”);
}throw new IOException(“”);
}
}
總結
- throw用於方法體中,用來拋出一個實際的異常對象,使用throw後,要麼使用try catch捕獲異常,要麼使用throws聲明異常
- throws用於方法聲明處,用來聲明該方法可能發生的異常類型,可以是多個異常類型,用來強制調用該方法時處理這些異常
- 抽象方法也可以使用throws,所以說並不是有throw纔有throws
- 如果使用throw關鍵字拋異常,一定不要使用Exception,不能很好標記異常類型
- 如果throw要拋出與業務邏輯有關的異常,需要使用自定義異常類
輸出結果
- java.lang.IllegalArgumentException: 參數異常,年齡最大不超過120
at Exception2.Throw1.big(Throw1.java:19)
at Exception2.Throw1.bang(Throw1.java:15)
at Exception2.Throw1.main(Throw1.java:8)
- java.lang.IllegalArgumentException: 參數異常,年齡最大不超過120
自定義異常
- 自定義異常就是自己定義的異常類,也就是Exception直接或間接的子類
- 自定義異常類
- public class 異常類名 extends Exception{
public 異常類名(String msg){
super(msg);
}
}
- public class 異常類名 extends Exception{
自定義異常類中往往不寫其他方法,只重載需要使用的構造方法
自定義異常示例
- public class BusinessException extends IOException{
public BusinessException() {
super();
}
public BusinessException(String message, Throwable cause) {
super(message, cause);}
}在程序中使用自定義異常大致可以分爲一下幾步
- 創建自定義異常類
- 在方法中通過throw 關鍵字拋出自定義異常
- 如果在當前拋出異常的方法中處理異常,可以使用try-catch語句捕獲並處理,否則在方法的聲明處通過throws關鍵字聲明該異常
- 調用throws聲明該異常的方法時,使用try catch捕獲自定義的異常類型,並在catch中進行處理