Java 異常

1 什麼是java異常

 異常是指在程序運行時,阻礙程序正常執行的錯誤事件。比如:用戶輸入錯誤數據、硬件故障、網絡阻塞等都會導致出現異常。 只要產生了異常,一個異常對象就會被創建,JRE就會試圖尋找異常處理程序來處理異常。

2 Java異常層級

  • Throwable是所有異常的父類,它有兩個直接子對象Error,Exception;
  • Error :運行時錯誤;Error對象由JVM生成並拋出,大多數錯誤與開發者無關,所以開發者也不用處理;如:OutOfMemoryError(內存溢出錯誤)、NoClassDefFoundError(類定義錯誤)、LinkageError(鏈接錯誤)等;

 Exception分爲檢查型異常和非檢查型異常:

  • 檢查型異常:所謂檢查(Checked)是指編譯器必須檢查這類異常,檢查的目的一方面是因爲該類異常的發生難以避免,另一方面就是讓開發者去解決掉這類異常,所以稱爲必須處理(try …catch)的異常如果不處理這類異常,集成開發環境中的編譯器一般會給出錯誤提示

 例如:一個讀取文件的方法代碼邏輯沒有錯誤,但程序運行時可能會因爲文件找不到而拋出FileNotFoundException,如果不處理這些異常,程序將來肯定會出錯。所以編譯器會提示你要去捕獲並處理這種可能發生的異常,不處理就不能通過編譯.

  • 非檢查型異常:所謂非檢查(Unchecked)是指編譯器不會檢查這類異常,不檢查的話則開發者在代碼的編輯編譯階段就不是必須處理,這類異常一般可以避免,因此無需處理(try …catch)。如果不處理這類異常,集成開發環境中的編譯器也不會給出錯誤提示。RuntimeException都屬於Unchecked。

 例如:你的程序邏輯本身有問題,比如數組越界、訪問null對象,這種錯誤你自己是可以避免的。編譯器不會強制你檢查這種異常。

3 異常方法

 下面的方法都是Throwable的主要方法:

方法 說明
public String getMessage() 返回異常信息
public Throwable getCause() 返回產生異常的原因
public void printStackTrace() 打印棧軌跡信息到標準錯誤流

4 異常處理

4.1 捕獲異常try catch

try
{
   // 保護代碼:可能有異常的代碼
}catch(ExceptionName e1)
{
   //Catch 塊
}

4.2 多重catch

try{
   // 保護代碼:可能有異常的代碼
}catch(ExceptionType1 e1){
  // 程序代碼
}catch(ExceptionType2 e2){
  // 程序代碼
}catch(ExceptionType3 e2){
  // 程序代碼
}
  • 如果保護代碼發生異常,異常被拋給第一個 catch 塊;如果拋出異常的類型與 ExceptionType1匹配,它在這裏就會被捕獲,不會繼續向下傳遞;如果不匹配,它會被傳遞給第二個 catch 塊;如此,直到異常被捕獲或者通過所有的 catch 塊。
  • 範圍小的異常類(子類)在上面,範圍大的異常類(父類)在下面
  • 儘量不要用try-catch嵌套,結構差;
  • 一個catch子句中可以捕獲多個異常,但是並列的異常類型不能具有繼承關係;
    catch(IOException | SQLException e)

4.3 throws/throw

  • throws在方法的簽名處聲明此方法可能拋出異常;

  • 如果一個方法存在可能有異常的代碼,要進行異常處理要麼對可能有異常的代碼try-catch要麼 throws給其調用者處理;

  • 可以使用 throw關鍵字拋出一個異常,無論它是新實例化的還是剛捕獲到的。

5 finally

try{
 // 保護代碼:可能有異常的代碼
}catch(Exception e){
  // 異常處理
}finally{
  // 可有可無,finally代碼塊一定會被執行,進行一些清理類型的收尾善後工作
}

6 自定義異常

  • 通過繼承Exception類或其子類來實現自定義異常類;
//自定義異常類:分數越界異常
public class OutOfScoreBoundException extends Exception{
    public OutOfScoreBoundException(String message) {
        super(message);
    }
    public OutOfScoreBoundException() {
        super();
    }
}
public class ExceptionDemo {
    public static boolean isScoreLegal(int score) throws Exception {//也可以throws OutOfScoreBoundException
        if(score>150||score<0){
            //拋出自定義異常,下面兩種方式都可以
//            throw new Exception("Your score is out of bound");
            throw new OutOfScoreBoundException("Your score is out of bound !");
        }else {
            return true;
        }
    }
 
    public static void main(String[] args) {//並列catch的Exception類型由小到大
        Scanner scanner=new Scanner(System.in);
        int score=scanner.nextInt();
        try {
            if (isScoreLegal(score)){
                System.out.println("Your score is legal !");
            }
        } catch (OutOfScoreBoundException e){
            e.printStackTrace();
            System.out.println("---->OutOfScoreBoundException");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("---->Exception");
        }
    }
}
160
---->OutOfScoreBoundException
OutOfScoreBoundException: Your score is out of bound !
	at ExceptionDemo.isScoreLegal(ExceptionDemo.java:13)
	at ExceptionDemo.main(ExceptionDemo.java:23)

7 常見相關面試題

(1)檢查型異常和非檢查型異常的區別?

  • 檢查型異常:編譯器必須檢查的異常,此類異常難以避免;開發者必須處理(try-catch),如果不處理,編譯器會有錯誤提示;
  • 非檢查型異常:編譯器不用檢查的異常,此類異常可以避免也必須避免;開發者不用處理(try-catch);

(2)throws/throw有什麼區別?

  • throws在方法的簽名處聲明此方法可能拋出異常;
  • 可以使用 throw關鍵字拋出一個異常,無論它是新實例化的還是剛捕獲到的。

(3) main方法拋出異常時發生了什麼?

  • 當main方法拋出異常時,Java運行終止並在控制檯打印異常信息和棧軌跡。

8 參考博客

https://www.runoob.com/java/java-exceptions.html
http://www.importnew.com/7383.html

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