1. 程式人生 > >異常的丟擲和捕捉

異常的丟擲和捕捉

  這節課來學習異常的丟擲和捕捉。

 

首先,什麼叫丟擲異常?程式碼解釋。

算了,常用異常類以後看到了再講。

接下來所有編譯時異常類我們就直接拋Exception,執行時異常拋RuntimeException

 

Demo1:

//我們選擇繼續丟擲

public static void main(String[] args) throws Exception {

    Scanner scanner  = new Scanner(System.in);

    int a = scanner.nextInt();

    exceptionThrowTest(a);  //因為exceptionThrowTest方法是選擇向外層拋異常,所以異常會被丟擲到這一層,這個時候我們還是要選擇捕獲或者繼續丟擲

}



//先來寫個方法吧

//向外丟擲異常,這是一個宣告,表明這個方法裡丟擲的異常最後會向外層拋

//什麼叫外層呢?呼叫這個方法的那一層就叫這個方法的外層

public static void exceptionThrowTest(int a) throws Exception

{

    if (a<0)

    {

        //丟擲異常

        throw new Exception("傳入的引數不可以為負數");//這裡報紅,說明編譯時異常必須被顯示丟擲或捕獲

    }

}

 

輸入:

-2

 

輸出:

Exception in thread "main" java.lang.Exception: 傳入的引數不可以為負數

 

上節課說過,如果最外層沒有捕獲異常,程式會直接停止執行並列印異常資訊

 

異常資訊的結構就是:

異常名+在哪裡出異常+異常全類名: 異常裡的detailMessage屬性

 

原始碼摘取:

public Exception(String message) {

    super(message);

}

 

public Throwable(String message) {

    fillInStackTrace();

    detailMessage = message;

}

 

可以看到輸出的就是我們傳給Exception構造器的那個字串引數

 

接下來看執行時異常

 

Demo2:

public static void main(String[] args){

    Scanner scanner  = new Scanner(System.in);

    int a = scanner.nextInt();

    runtimeExceptionThrowTest(a);

}

 

public static void runtimeExceptionThrowTest(int a)

{

    if (a<0)

    {

        //丟擲異常

        throw new RuntimeException("傳入的引數不可以為負數");//這裡報紅,說明編譯時異常必須被顯示丟擲或捕獲

    }

}

 

輸入:

-2

 

輸出:

Exception in thread "main" java.lang.RuntimeException: 傳入的引數不可以為負數

 

結論:執行時異常的丟擲可以不必被顯示捕獲或丟擲,如果不被顯示捕獲和丟擲,預設向外層丟擲

 

接下來看異常的捕獲:

異常的捕獲需要用到try-catch語法結構,還是直接看程式碼:

 

被try/catch包裹

 

 

try-catch語法:

 

 

 

try{

可能會丟擲異常的程式碼片段

}catch(異常類 變數名){

處理程式碼

}

 

Demo 3:

public static void main(String[] args){

    Scanner scanner  = new Scanner(System.in);

    int a = scanner.nextInt();

    //我們來手寫一下

    try{

        //可能會丟擲異常的片段

        exceptionThrowTest(a);

    }catch(Exception e){

        System.out.println("出異常啦");

    }



    System.out.println("異常已經被捕獲並且處理啦,程式還是會繼續執行,不會終止的哦");

}

 

輸入:

-3

 

輸出:

出異常啦

異常已經被捕獲並且處理啦,程式還是會繼續執行,不會終止的哦

 

結論:

  1. 如果丟擲的異常被捕獲了,程式會繼續執行,而不會終止執行。
  2. try塊裡的程式碼如果丟擲異常,則try塊裡的程式碼不會繼續執行,而是轉到catch塊裡執行。
  3. 一個try可以對應多個catch,catch的規則應該是先catch子類異常,後catch父類異常,且一個異常只會被catch一次
  4. 所有異常都繼承自Exception,所以在最後catch一下Exception是一個好習慣
  5. 執行時異常也可以被catch哦

 

Demo 4:

public static void main(String[] args){

    Scanner scanner  = new Scanner(System.in);

    int a = scanner.nextInt();

    //我們來手寫一下

    try{

        runtimeExceptionThrowTest(a);

        exceptionThrowTest(a);

    }catch (RuntimeException e){

        System.out.println("這裡被RuntimeException捕獲啦");

        e.printStackTrace();    //輸出異常資訊

    } catch(Exception e){

        System.out.println("出異常啦");

        e.printStackTrace();    //輸出異常資訊

    }

    //runtimeExceptionThrowTest(a);

    System.out.println("異常已經被捕獲並且處理啦,程式還是會繼續執行,不會終止的哦");

}





public static void exceptionThrowTest(int a) throws Exception

{

    if (a>0)

    {

        //丟擲異常

        throw new Exception("傳入的引數不可以為正數");//這裡報紅,說明編譯時異常必須被顯示丟擲或捕獲

    }

}



public static void runtimeExceptionThrowTest(int a)

{

    if (a<0)

    {

        //丟擲異常

        throw new RuntimeException("傳入的引數不可以為負數");//這裡報紅,說明編譯時異常必須被顯示丟擲或捕獲

    }

}

 

輸入:

2

 

輸出:

出異常啦

java.lang.Exception: 傳入的引數不可以為正數

         at helloworld.exception.ExceptionTeach.exceptionThrowTest(ExceptionTeach.java:34)

         at helloworld.exception.ExceptionTeach.main(ExceptionTeach.java:14)

異常已經被捕獲並且處理啦,程式還是會繼續執行,不會終止的哦

 

輸出順序應該是上面這樣的,idea輸出的順序不太符合我們預想的結果哈,不過內容輸出的沒錯,只是順序問題而已,這個應該是idea的問題

分析:

輸入2,丟擲的是Exception異常,所以不會捕獲RuntimeException異常,也就不會輸出”這裡被RuntimeException捕獲啦”

 

輸入:

-1

輸出:

這裡被RuntimeException捕獲啦

java.lang.RuntimeException: 傳入的引數不可以為負數

         at helloworld.exception.ExceptionTeach.runtimeExceptionThrowTest(ExceptionTeach.java:43)

         at helloworld.exception.ExceptionTeach.main(ExceptionTeach.java:13)

異常已經被捕獲並且處理啦,程式還是會繼續執行,不會終止的哦

 

分析:

這個顯然捕獲的是RuntimeException啦,而且根據輸出資訊可以看出異常只會被捕獲一次,因為處理Exception異常的程式碼並沒有被執行

 

注意:

差點忘記說了,這裡的是throws,表明可以丟擲多個異常,多個異常用逗號隔開
throws丟擲的異常不一定會被丟擲,throws只是負責向外拋這個方法捕獲到的異常,不負責判斷這個異常到底有沒有被捕獲到,所以throws後面可以隨便寫
但是,throws後面必須包含本方法可能被丟擲的異常,除非這個異常在本方法內已經被捕獲了或者這個異常是執行時異常

 

 

這個就是異常的丟擲和捕獲。