Java異常處理與自定義異常


一、何為異常

        異常:在Java語言中,將程序執行中發生的不正常情況稱為“異常”。(開發過程中的語法錯誤和邏輯錯誤不是異常)
        Java程序在執行過程中所發生的異常事件可分為兩類:
                Error:  Java虛擬機無法解決的嚴重問題。如:JVM系統內部錯誤、資源耗盡等嚴重情況。一般不編寫針對性的代碼進行處理。
                Exception: 其它因編程錯誤或偶然的外在因素導致的一般性問題,可以使用針對性的代碼進行處理。例如:
                        空指針訪問
                        試圖讀取不存在的文件
                        網絡連接中斷

        對於這些錯誤,一般有兩種解決方法:一是遇到錯誤就終止程序的運行。另一種方法是由程序員在編寫程序時,就考慮到錯誤的檢測、錯誤消息的提示,以及錯誤的處理。

        捕獲錯誤最理想的是在編譯期間,但有的錯誤只有在運行時才會發生(分類:編譯時異常和運行時異常)。比如:除數為0,數組下標越界等。

       運行時異常, 是指編譯器不要求強制處置的異常。一般是指編程時的邏輯錯誤,是程序員應該積極避免其出現的異常。java.lang.RuntimeException類及它的子類都是運行時異常。 對於這類異常,可以不作處理,因為這類異常很普遍,若全處理可能會對程序的可讀性和運行效率產生影響。

        編譯時異常,是指編譯器要求必須處置的異常。即程序在運行時由於外界因素造成的一般性異常。編譯器要求java程序必須捕獲或聲明所有編譯時異常。 對於這類異常,如果程序不處理,可能會帶來意想不到的結果。

 

二、常見異常

 

java.lang.RuntimeException 
ClassCastException
ArrayIndexOutOfBoundsException
NullPointerException
ArithmeticException
。。。
java.io.IOExeption
FileNotFoundException
EOFException
java.lang.ClassNotFoundException
java.lang.InterruptedException
java.io.FileNotFoundException
java.sql.SQLException

  

 三、Java異常處理機制

        Java采用異常處理機制,將異常處理的程序代碼集中在一起,與正常的程序代碼分開,使得程序簡潔,並易於維護。Java提供的是異常處理的抓拋模型。Java程序的執行過程中如出現異常,會生成一個異常類對象,該異常對象將被提交給Java運行時系統,這個過程稱為拋出(throw)異常。

        異常對象的生成,可由虛擬機自動生成:程序運行過程中,虛擬機檢測到程序發生了問題,如果在當前代碼中沒有找到相應的處理程序,就會在后台自動創建一個對應異常類的實例對象並拋出——自動拋出;也可由開發人員手動創建:Exception exception = new ClassCastException();——創建好的異常對象不拋出對程序沒有任何影響,和創建一個普通對象一樣。

        如果一個方法內拋出異常,該異常對象會被拋給調用者方法中處理。如果異常沒有在調用者方法中處理,它繼續被拋給這個調用方法的上層方法。這個過程將一直繼續下去,直到異常被處理。這一過程稱為捕獲(catch)異常。如果一個異常回到main()方法,並且main()也不處理,則程序運行終止。

        程序員通常只能處理Exception,而對Error無能為力。異常處理是通過try-catch-finally語句實現的。

try{    
......    //可能產生異常的代碼
}catch( ExceptionName1 e ){ 
   ......    //當產生ExceptionName1型異常時的處置措施
}catch( ExceptionName2 e ){......     //當產生ExceptionName2型異常時的處置措施}  
[ finally{
......     //無論是否發生異常,都無條件執行的語句       
 }  ]

 

四、捕獲異常

1、try 
        捕獲異常的第一步是用try{…}語句塊選定捕獲異常的范圍,將可能出現異常的代碼放在try語句塊中。
2、catch (Exceptiontype e)
        在catch語句塊中是對異常對象進行處理的代碼。每個try語句塊可以伴隨一個或多個catch語句,用於處理可能產生的不同類型的異常對象。
如果明確知道產生的是何種異常,可以用該異常類作為catch的參數;也可以用其父類作為catch的參數。
        比如:可以用ArithmeticException類作為參數的地方,就可以用RuntimeException類作為參數,或者用所有異常的父類Exception類作為參數。但不能是與ArithmeticException類無關的異常,如NullPointerException(catch中的語句將不會執行)。

        捕獲異常的有關信息,與其它對象一樣,可以訪問一個異常對象的成員變量或調用它的方法。

        getMessage()   獲取異常信息,返回字符串

        printStackTrace()  獲取異常類名和異常信息,以及異常出現在程序中的位置。返回值void。

 

 

 

 

3、finally
        捕獲異常的最后一步是通過finally語句為異常處理提供一個統一的出口,使得在控制流轉到程序的其它部分以前,能夠對程序的狀態作統一的管理。
不論在try代碼塊中是否發生了異常事件,catch語句是否執行,catch語句是否有異常,catch語句中是否有return,finally塊中的語句都會被執行。finally語句和catch語句是任選的。

 

 

        RuntimeException類或是它的子類,這些類的異常的特點是:即使沒有使用try和catch捕獲,Java自己也能捕獲,並且編譯通過  ( 但運行時會發生異常使得程序運行終止 )。 如果拋出的異常是IOException等類型的非運行時異常,則必須捕獲,否則編譯錯誤。也就是說,我們必須處理編譯時異常,將異常進行捕捉,轉化為運行時異常 。

 

五、聲明拋出異常

        聲明拋出異常(throws)是Java中處理異常的第二種方式。如果一個方法(中的語句執行時)可能生成某種異常,但是並不能確定如何處理這種異常,則此方法應顯示地聲明拋出異常,表明該方法將不對這些異常進行處理,而由該方法的調用者負責處理。
        在方法聲明中用throws語句可以聲明拋出異常的列表,throws后面的異常類型可以是方法中產生的異常類型,也可以是它的父類。
聲明拋出異常舉例:
    public void readFile(String file)  throws FileNotFoundException {
        ……
        // 讀文件的操作可能產生FileNotFoundException類型的異常
        FileInputStream fis = new FileInputStream(file);
         ..……
     }

 

 

    重寫方法聲明拋出異常的原則:重寫方法不能拋出比被重寫方法范圍更大的異常類型。在多態的情況下,對其方法的調用-異常的捕獲按父類聲明的異常處理。
        Java異常類對象除在程序執行過程中出現異常時由系統自動生成並拋出,也可根據需要人工創建並拋出。
        首先,要生成異常類對象,然后通過throw語句實現拋出操作(提交給Java運行環境)。
                IOException e = new IOException();
                throw e;
        可以拋出的異常必須是Throwable或其子類的實例。下面的語句在編譯時將會產生語法錯誤:
                throw new String("want to throw");
 

六、創建用戶自定義異常類

       一般地,用戶自定義異常類都是RuntimeException的子類。自定義異常類通常需要編寫幾個重載的構造器;自定義的異常類對象通過throw拋出;自定義異常最重要的是異常類的名字,當異常出現時,可以根據名字判斷異常類型。
      用戶自定義異常類MyException,用於描述數據取值范圍錯誤信息。用戶自己的異常類必須繼承現有的異常類。 

 

#  自定義異常舉例
public class MyRuntimeException extends RuntimeException {
    private static final long serialVersionUID = 998783281801529147L;

    public MyRuntimeException(String message) {
        super(message);
    }

    public MyRuntimeException(Throwable e) {
        super(ExceptionUtil.getMessage(e), e);
    }

    public MyRuntimeException(String messageTemplate, Object... params) {
        super(StrUtil.format(messageTemplate, params));
    }

    public MyRuntimeException(String message, Throwable throwable) {
        super(message, throwable);
    }

    public MyRuntimeException(Throwable throwable, String messageTemplate, Object... params) {
        super(StrUtil.format(messageTemplate, params), throwable);
    }
}

  

 

————————————————

本篇文章同步在個人公眾號:

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM