java異常

java異常的定義

      不要指望你的程序永遠不會出錯。Java程序運行過程中所發生的異常事件,比如除數爲零、文件找不到等,就叫做java異常。Java把異常當作一個對象來處理,使用Throwable類及其子類來描述異常。

java異常體系結構

Java異常類層次結構圖

      Thorwable類所有異常和錯誤的超類,有兩個子類Error和Exception,分別表示錯誤和異常。 Exception又分爲RuntimeException和非RuntimeException。包括Error與RuntimeException及其子類屬於非檢查性(unchecked)異常,而Exception除了RuntimeException及其子類的其他非RuntimeException及其子類是檢查性(checked)異常。

java需要異常處理的對象

  • Error是指JVM系統內部錯誤、資源耗盡等嚴重情況,在這種情況下,程序會終止運行。Error是一種unchecked Exception,沒有必要捕捉Error,你只需要通知用戶即可。

  • RuntimeException是表示執行期間發生的任何意外事故中被拋出的異常;也就是說,它表示如果程序運行正常,從不會發生的情況。這類異常皆由Java系統自動拋出,不需要手工拋出。Error和RuntimeException都是unchecked Exception,通常都不需要程序員來捕捉和處理,因爲一個正確設計和實現的程序從不出現這種異常,通常對它不做處理。RuntimeException是程序存在邏輯錯誤,要對程序進行修改。

  • Checked Exception異常。JAVA 語言規定必須對checked Exception作處理,編譯器會對此作檢查,要麼在方法體中聲明拋出checked Exception,要麼使用catch語句捕獲checked Exception進行處理,不然不能通過編譯。

Java異常處理機制

  • Java程序的執行過程中如出現異常,會自動生成一個異常類對象,該異常類對象將被提交給Java運行時系統,這個過程成爲拋出(throw)異常。

  • 當Java運行時系統接收到異常對象時,會尋找能處理這一異常的代碼並把當前異常對象交給其處理,這一過程稱爲捕獲(catch)異常。

  • 如果Java運行時系統找不到可以捕獲異常的方法,則運行時系統將終止,相應的Java程序也將退出。

  • 程序員通常只能處理違例(Exception),而對錯誤(Error)無能爲力。

          如果方法中的一個語句拋出一個沒有在相應的try/catch塊中處理的異常,那麼這個異常就被拋出到調用它方法中。如果異常也沒有在調用方法中被處理,它就被拋出到該方法的調用程序。這個過程要一直延續到異常被處理。如果異常到這時還沒被處理,它便回到main(),而且,即使main()不處理它,那麼,該異常就異常地中斷程序。

Java異常處理的方法

這裏寫圖片描述

try{
    //可能會拋出特定異常的代碼段 
}catch(MyExceptionType myException){
    //如果myException被拋出,則執行這段代碼
} catch(Exception otherException){
    //如果另外的異常otherException被拋出,則執行這段代碼
}finally{
    //無條件執行的語句
}
  1. 在可能出現異常的地方throw(拋出)異常。異常可以由JVM拋出,也可以手工拋出。手工拋出異常用throw關鍵字,在可能出現異常的代碼塊放在try關鍵字的塊中。RuntimeException可以由JVM自動拋出,不需要throw手動拋出。

  2. 要處理異常,先將能夠拋出異常的代碼放入try塊中,然後再創建相應的catch塊的列表,每個可以被拋出異常都有一個。如果生成的異常與catch中提到的相匹配,那麼catch條件的塊語句就被執行。在try塊之後,可能有許多catch塊,每一個都處理不同的異常。catch只有第一個匹配try塊中的異常起作用,下面的其他catch塊都不會執行。因此通常把子類或者更詳細的異常放在前面,不父類或者範圍廣的異常放在後面,Exception可以放在最後面,以此來保證捕獲到最精準的異常類型。

  3. finally語句總是要執行的,不管是否拋出異常。只有唯一的一種情況finally語句不執行,就是在前邊的塊中有System.exit()的方法被執行時。如果一個return語句被嵌入try塊內的代碼中,那麼,finally塊中的代碼應在return前執行。
public class Excep {
    public static void main(String[] args) {
        int c = 0;
        try{
            int a = 6;
            int b = 0;
            c = a / b;
            System.out.println(c);
        }catch(ArithmeticException e){
            System.out.println("ArithmeticException-----------");
            e.printStackTrace();
        }
        catch(Exception e){
            System.out.println("Exception------------------");
            e.printStackTrace();
        }
        finally{
            System.out.println("Finally------------------");
        }
    }
}
//運行結果爲
//ArithmeticException-----------
//Finally------------------
public class Excep {
    public static void main(String[] args) {
        int c = 0;
        try{
            int a = 6;
            return;
        }
        catch(Exception e){
            System.out.println("Exception------------------");
            e.printStackTrace();
        }
        finally{
            System.out.println("Finally------------------");
        }
    }
}
//運行結果爲:Finally------------------

      當把return換成System.exit(0)時,finally塊中的內容就不能執行了。

處理異常or拋出異常?

  • 爲了寫出健壯的代碼,Java編程語言要求,當一個方法發生Exception(不包括Error或RuntimeException)時,該方法必須決定如果出現問題該採取一種措施。
  • 這種措施有兩種:
    1.直接處理異常。通過將try{}catch(){}塊納入其代碼中,在這裏捕獲給被命名爲屬於某個超類的異常,並調用方法處理它。即使catch塊是空的,這也算是處理情況。
    2.或者拋出異常讓調用該方法的代碼處理該異常。讓被調用的方法表示它將不處理異常,而且該異常將被拋回到它所遇到的調用方法中。它是按如下所示通過用throws子句標記的該調用方法的聲明來實現的:
  public void reader() throws IOException
  • 關鍵字throws之後是所有異常的列表,方法可以拋回到它的調用程序中。儘管這裏只顯示了一個異常,如果有成倍的可能的異常可以通過該方法被拋出,那麼,可以使用逗號分開的列表。
public void reader() throws IOException,FileNotFoundException{}
  • 是選擇處理異常,還是選擇拋出一個異常取決於是否給你自己或你的調用程序一個更合適的候選的辦法來處理異常。如果有足夠的信息來處理這個異常,你就可以不用拋出給調用者,而直接處理這個異常;而如果當前信息不足以或者你不知道如何處理,就可以把異常信息拋出給上一層調用者。

自定義異常

      所謂自定義異常,通常就是定義一個類,去繼承Exception類或者它的子類。因爲異常必須直接或者間接地繼承自Exception類。

public class MyException extends Exception{
    MyException(){
        super();
    }
    MyException(String message){
        super(message);
    }
}
public class TestException {
    public void notZero(int i) throws MyException{
        if(i == 0)
        {
            throw new MyException("參數不能爲0");
        }
        else{
            System.out.println("傳入的參數爲: "+i);
        }
    }
    public static void main(String[] args) {
        TestException t = new TestException();
        try {
            t.notZero(0);
        } catch (MyException e) {
            e.printStackTrace();
        }finally{
            System.out.println("finally");
        }
    }
}
//運行結果爲:
/*test.MyException: 參數不能爲0
    at test.TestException.notZero(TestException.java:7)
    at test.TestException.main(TestException.java:16)
  finally
*/

      注意當方法中使用throw拋出檢查性異常時,在方法名後要加上throws+拋出的異常類型。

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