Java中異常常見問題總結

問題1:try/catch/finally執行順序問題

1.代碼

  • 問下述代碼能否編譯通過?如果能,輸出是?
public class Demo03 {


    public static void main(String[] args) {


        try {
            String s = null;
            
            return;
        }catch (Exception e){
            System.out.println("catch");
        }finally {
            System.out.println("finally");
        }
    }

}

2.分析

  • 上述代碼可以編譯通過,輸出finally
    在這裏插入圖片描述

  • 這其實很簡單,進入try代碼塊,執行return前的內容,然後沒有發生異常則進入到finally代碼塊中的內容,然後再執行return

3.問題1.1

  • 下述代碼能否編譯通過?輸出是?
public class Demo03 {
    public static void main(String[] args) {
        try {
            String s = null;
            System.exit(0);
//            return;
        }catch (Exception e){
            System.out.println("catch");
        }finally {
            System.out.println("finally");
        }
    }

}
  • 可以編譯通過,什麼都不輸出
    在這裏插入圖片描述

  • 注意到代碼System.exit(0);,遇到它的時候就不會再去執行finally中的代碼,而是直接退出程序,這表示結束正在運行中的虛擬機

  • 一般來說finally中的代碼是一定會被執行的,但是這是唯一的特殊情況,因爲虛擬機都沒了,後面的代碼肯定都沒辦法執行

問題2:兩類異常的不同處理方式

運行期異常,編譯期異常

1.問題引入

  • 下述代碼能否編譯通過
public class ExceptionTest {
    
    
    public void doSomething() throws ArithmeticException{
        System.out.println("do");   
    }
    public static void main(String[] args) {
        ExceptionTest test = new ExceptionTest();
        test.doSomething();
    }
}
  • 可以通過,ArithmeticException是一個運行期異常,可以對其不做處理,最後會被拋出到虛擬機中處理

  • 下述代碼能否編譯通過?

public class ExceptionTest {
    public void doSomething() throws IOException {
        System.out.println("do");
    }
    public static void main(String[] args) {
        ExceptionTest test = new ExceptionTest();
        test.doSomething();
    }
}

  • 不能,IOException是一個編譯期異常, 必須顯式的向上拋出
    在這裏插入圖片描述

  • 修改上述代碼,可以編譯通過
    在這裏插入圖片描述

2小結

上述問題的本質是對於兩種不同異常處理方式

  • checked exception:編譯期異常,都是java.lang.Exception 的子類,必須進行處理,有兩種處理方式
    • 繼續向上拋出,消極的做法,直到跑到JVM
    • 主動的用try...catch進行處理
  • unchecked exception:運行期異常,都是java.lang.RuntimeException的子類,可以不出力

2.1異常類的繼承結構

那我們如何能區分哪些異常屬於編譯期異常,哪些屬於運行期異常呢?

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

問題3:try…catch捕獲異常時的順序問題

異常範圍大的放下面,範圍小的放前面

1問題

  • 下述代碼,編譯能否通過
public class ExceptionTest2 {

    public void doSomething01() throws IOException{
        System.out.println("do");
    }

    public static void main(String[] args) {

        ExceptionTest2 test = new ExceptionTest2();

        try {
            test.doSomething01();
        } catch (Exception e) {
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    
}
  • 不能
    在這裏插入圖片描述

  • 第一個catch是所有異常類的父類,不管try中發生何種異常都會進入到第一個catch的代碼塊中

  • 而只要進入了一個catch後面所有的catch就不會再被進入了,所有發生了編譯錯誤

  • 當使用多個catch來捕獲異常的時候一定要注意範圍問題:異常範圍大的放下面,範圍小的放上面

  • 調整順序後,編譯通過
    在這裏插入圖片描述

  • 一般情況下,我們一般只用一個catch來捕獲Exception類的異常即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章