注意:想在catch的參數里使用自定義的異常,則必須先將這個異常拋出才行。(throws是具有拋出異常的能力,並未拋出,throw new MyException是拋出異常,catch是捕獲異常,只有拋出,才能被捕獲)
1 異常的拋出原理:
java的錯誤其實也是一些類文件,它們之所以可以在程序出錯時被拋出,是因為在你調用了某些方法的時候,為這些方法需要做一些預先的處理,比如你要調用一個對象的一個屬性,如果你所調用的對象是空的話,那么程序是不可以執行的,但是又不能不告訴你,所以就用一個錯誤來提示你。
異常被拋出,肯定是因為帶有異常檢查的方法被調用了,可以在構造方法,中進行指定,當別人調用這些方法的時候,並且沒有通過檢查,那么exception就會被拋出或者被捕獲。而調用這個方法的方法,要么捕獲要么繼續拋出交給它的父類去處理。總之:只要是會出現異常的地方,只有兩種處理方式,第一:使用try和catch進行捕獲。第二:把錯誤交給父類去處理,就是throws exception。
這些錯誤提示,或者在你所調用的方法里面有所定義,或者是在虛擬機JVM運行時候有所定義。在虛擬機運行時候拋出的異常就是 運行時異常,包括 NullPointExcetion,ClassCastException,IndexOutOfBoundsException。總之:它肯定是存在的,我們有時在想,我根本就沒有在我自己定義類里面的方法上添加異常,可是它也會拋出異常,這是因為類在程序判斷的時候,滿足了某些條件,於是程序就自動實例化了一個錯誤的對象,然后把這個錯誤給拋了出來,比如說NullPointerException空指針異常,你可能會說這個錯誤的話,我找不到它定義在哪里啊?可是你要知道的是,你的方法終究是要運行的,當你運行的時候,虛擬機在執行方法的時候它是會進行檢查的,它檢查的時候當然也是調用方法了,而在調用之前,它會把對你將要調用的對象進行檢查,如果有錯就會實例化一個NullPointerException出來,檢查是很容易理解的事情,就像你實例化了一個類,然后在運行的時候,對這個類的一些信息進行判斷,只是jvm檢查的比較復雜,但是思想肯定是一致的。
2 異常的分析:
在我們運行程序的時候,如果出現了,錯誤,那么異常信息會被打印出來,打印的時候的順序是:先打印此類所在的繼承鏈的父類的異常信息,之后再打印子類,以此類推。因為什么呢?因為對象實例化的過程也就是這個順序,所以打印的時候順序也是一樣的,當然如果你已經對錯誤進行了處理的話,那么自然父類的錯誤就不會被打印出來了,所以說當出現異常的時候,那些最先打印出來的都是父類的信息,你出錯的調用位置應該是在下邊子類中。
自定義異常:
測試自定義錯誤:
拋出 Exception:
java的錯誤其實也是一些類文件,它們之所以可以在程序出錯時被拋出,是因為在你調用了某些方法的時候,為這些方法需要做一些預先的處理,比如你要調用一個對象的一個屬性,如果你所調用的對象是空的話,那么程序是不可以執行的,但是又不能不告訴你,所以就用一個錯誤來提示你。
異常被拋出,肯定是因為帶有異常檢查的方法被調用了,可以在構造方法,中進行指定,當別人調用這些方法的時候,並且沒有通過檢查,那么exception就會被拋出或者被捕獲。而調用這個方法的方法,要么捕獲要么繼續拋出交給它的父類去處理。總之:只要是會出現異常的地方,只有兩種處理方式,第一:使用try和catch進行捕獲。第二:把錯誤交給父類去處理,就是throws exception。
這些錯誤提示,或者在你所調用的方法里面有所定義,或者是在虛擬機JVM運行時候有所定義。在虛擬機運行時候拋出的異常就是 運行時異常,包括 NullPointExcetion,ClassCastException,IndexOutOfBoundsException。總之:它肯定是存在的,我們有時在想,我根本就沒有在我自己定義類里面的方法上添加異常,可是它也會拋出異常,這是因為類在程序判斷的時候,滿足了某些條件,於是程序就自動實例化了一個錯誤的對象,然后把這個錯誤給拋了出來,比如說NullPointerException空指針異常,你可能會說這個錯誤的話,我找不到它定義在哪里啊?可是你要知道的是,你的方法終究是要運行的,當你運行的時候,虛擬機在執行方法的時候它是會進行檢查的,它檢查的時候當然也是調用方法了,而在調用之前,它會把對你將要調用的對象進行檢查,如果有錯就會實例化一個NullPointerException出來,檢查是很容易理解的事情,就像你實例化了一個類,然后在運行的時候,對這個類的一些信息進行判斷,只是jvm檢查的比較復雜,但是思想肯定是一致的。
2 異常的分析:
在我們運行程序的時候,如果出現了,錯誤,那么異常信息會被打印出來,打印的時候的順序是:先打印此類所在的繼承鏈的父類的異常信息,之后再打印子類,以此類推。因為什么呢?因為對象實例化的過程也就是這個順序,所以打印的時候順序也是一樣的,當然如果你已經對錯誤進行了處理的話,那么自然父類的錯誤就不會被打印出來了,所以說當出現異常的時候,那些最先打印出來的都是父類的信息,你出錯的調用位置應該是在下邊子類中。
自定義異常:
上面的分析可以知道,如果要自己定義異常的話,只需要自己定義一個類,這個類只需要集繼承Exception類,然后你可以為這個類指定構造方法,根據你自己的需求去打印出你想提示的信息,在拋出的時候,也就是在執行條件判斷后throw new MyException的時候,你可以指定異常的ID,這完全是你自己可以操作的事情,比如你想要在打印錯誤的同時,把錯誤的種類也打印出來就可以把下面的那個MyException的構造函數修改為:
測試舉例:
- <span style="font-size:14px;">package exception;
- public class MyException extends Exception {
- private static final long serialVersionUID = 1L;
- private int idNumber;
- public int getIdNumber() {
- return idNumber;
- }
- public MyException(String exception, int id) {
- super(exception);
- this.idNumber = id;
- }
- }</span>
測試自定義錯誤:
- package exception;
- public class TestMyExeption {
- public void regist(int num) throws MyException {
- if (num < 0) {
- throw new MyException("人數為負數不合理!", 1);
- }
- System.out.println("throw 之后的程序不能執行" + num);
- }
- /**
- * 把異常給拋出去,交給更高層處理
- *
- * @throws MyException
- */
- public void manager() throws MyException {
- regist(-100);
- }
- /**
- * 把異常給截獲並處理
- */
- public void manager1() {
- try {
- regist(-1330);
- } catch (MyException e) {
- // 在處理錯誤的時候,可以根據自己的需要去打印錯誤的信息
- System.out.println("出錯了,錯誤的編號:" + e.getIdNumber());
- }
- System.out.println("程序可以繼續執行!");
- }
- public static void main(String[] args) throws MyException {
- new TestMyExeption().manager();
- // new TestMyExeption().manager1();
- }
- }
拋出 Exception:
- package exception;
- import java.util.Scanner;
- public class TestThrow {
- public static void main(String[] args) {
- TestThrow t = new TestThrow();
- System.out.print("請輸入您的年齡:");
- System.out.println("您的年齡:" + t.inputAge());
- }
- public int inputAge() {
- int result = -1;
- Scanner scan = new Scanner(System.in);
- while (true) {
- try {
- result = scan.nextInt();
- if (result < 0 || result > 130) {
- Exception me = new Exception("年齡超出合理范圍!");
- throw me;
- }
- break;
- } catch (Exception e1) {
- System.out.print(e1.getMessage() + "請重新輸入:");
- continue;
- }
- }
- return result;
- }
- }
- 頂