java異常處理機制的理解

參考《第一行代碼java》《java程序設計教程》
java中程序的錯誤有語法錯誤、語義錯誤。若是是語法性錯誤,在編譯時就能夠檢查出來並解決。語義錯誤是在程序運行時出現的,在編譯時沒有錯誤,但在運行時可能會出現錯誤致使程序退出,這些錯誤稱爲異常。在沒有異常處理的狀況下,也即默認狀況下,程序出現異常後會打印異常信息,同時終止執行異常以後的代碼。爲了讓程序在出現異常後仍然能夠正常執行完畢,必須引入異常處理語句完善代碼。所以,異常處理機制用於檢測和處理異常,提升java程序的健壯性。
在java中,全部的異常都當作對象處理,即當發生異常時產生了異常對象。java異常處理機制的語法爲:java

try{
    //可能出現異常的語句
}catch(異常類型 對象){
    //異常處理
}finally{
    //不論是否出現異常,仍會統一執行的代碼
}

try語句用於捕獲可能出現異常的代碼。catch語句根據不一樣的異常類型進行不一樣的異常處理,所以一個try語句能夠對應多個catch語句。若是try語句中產生異常,程序會跳轉到匹配異常類型的catch語句中,進行異常處理。無論程序是否產生異常,都會執行finally語句。finally語句能夠省略。若是省略了finally語句,程序在執行完catch語句後,會繼續向下執行。
catch語句和finally語句能夠省略,可是不能同時省略。異常格式的組合一般有以下三種:try...catch, try...catch...finally, try...finally。編程

異常的繼承結構

在java中,全部異常類型最高繼承類是Throwable。Throwable下面有兩個子類Error和Exception。java的異常子類命名都會使用***Error或***Exception的形式,開發者能夠根據這個特徵進行區分Error和Exception。
Error是JVM錯誤,屬於不可查錯誤。出現Error時程序因沒法處理,沒有執行。
Exception是程序運行中的錯誤,用戶可使用異常處理格式處理。異常分爲可查異常和不可查異常。
不可查異常是在運行中出現的異常。這類異常在編譯中可能出現,也可能不出現,因此在程序中能夠選擇處理這類異常,或者選擇不處理。RuntimeException和其子類屬於不可查異常。
可查異常是在編譯時被強制檢查的異常。這種異常能夠預見,所以必須在程序中進行處理,或進行捕獲和處理,或拋出給上一級調用方法到處理。不然,編譯將沒法經過。RuntimeException之外的異常都屬於可查異常。數組

圖片描述

常見異常

ArithmeticException:數學運算異常。
NullPointerException:空指針異常。
NegativeArraySizeException:數組大小爲負值異常。
ArrayIndexOutOfBoundException:數組下標越界異常。
NumberFormatException:數字格式異常。
InputMismatchException:輸入類型不匹配異常。
NoSuchMethodException:方法不存在異常。
DataFormatException:數據格式錯誤異常。
NoClassDefFoundError:未找到類定義錯誤。
OutOfMemoryError:內存不足錯誤。
StackOverflowError:堆棧溢出錯誤。
ThreadDeath:線程結束。
UnknownError:未知錯誤。spa

Throwable類的經常使用方法

public Throwable getCause() //返回Throwable對象的緣由。
public String getMessage() //返回Throwable對象的詳細信息
public void printStackTrace() //將此Throwable對象的堆棧跟蹤輸出至錯誤輸出流,做爲System.err的值

異常的處理流程

一、當程序出現異常,JVM自動根據異常的類型實例化一個與之類型匹配的異常類對象。
二、根據異常對象判斷是否存在異常處理。若是不存在異常處理,則由JVM對異常默認處理:輸出異常信息,結束程序調用。
三、若是存在異常捕獲操做,try語句捕獲異常類實例化對象,再與catch語句進行異常類型匹配,並處理異常。
四、不論是否匹配到catch語句,若是存在finally語句,就會執行finally語句代碼。
五、finally語句後面的代碼根據以前是否匹配到catch語句進行處理。若是匹配到catch語句,也即捕獲到異常,則繼續執行finally後的語句。若是沒有匹配到catch語句,則將異常交由JVM默認處理。
異常捕獲是一個異常類對象的傳遞過程,全部異常類對象均可以相父類對象轉型。所以能夠異常類對象可使用Exception接收,簡單實現異常處理。
對於異常分開處理仍是一塊兒處理的問題,沒有嚴格的規範,而是根據項目開發標準決定。異常分開處理便於代碼的維護,統一處理則能夠節省開發精力。
在處理多個異常時,範圍小的異常要放在範圍大的異常以前處理。不然,範圍小的異常會因異常處理完成而沒法處理。命令行

throws關鍵字

throws關鍵字用在方法的定義上,表示此方法不進行異常的處理,而是交給被調用到處理。線程

myMath.java
class myMath{
    public static int div(int x, int y) throws Exception{ //該方法不處理異常
        return x/y;
    }
}
exception_throws.java
public class exception_throws{
    public static void main(String args[]){
        try{ //div()方法拋出異常,這裏必須明確處理異常
            System.out.println(myMath.div(10,0));
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

throw關鍵字

throw關鍵字用於用戶手動拋出一個異常類實例化對象。設計

exception_throw.java
public class exception_throw{
    public static void main(String args[]){
        try{
            throw new Exception("self-defined exception"); //直接拋出自定義異常類對象
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

異常處理的標準格式

除在上面提到的三種異常組合格式,還有一種是try...catch...finally結合throw和throws的異常處理格式。指針

class myMath{
    public static int div(int x, int y) throws Exception{ //出現異常交給被調用處輸出
        System.out.println("===start===");
        int result = 0;
        try{
            result = x / y;
        }catch(Exception e){
            throw e; //向上拋出
        }finally{
            System.out.println("===end===");
        }
        return result;
    }
}
public class exception_standerd{
    public static void main(String args[]){
        try{
            System.out.println(myMath.div(10,0));  //被調用到處理異常
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

在本例中,也能夠將myMath.java中的catch語句省略。myMath.java中的try語句捕獲的異常經過div()方法拋出給調用到處理。code

RuntimeException類

RuntimeException的子類對象能夠根據用戶須要進行有選擇的處理,程序在編譯時不會強制性要求用戶處理異常,因此在調用時不處理也不會有任何編譯錯誤。若是沒有處理卻發生異常,則交給JVM默認處理。
例如Integer類中的parseInt()方法orm

public static int  parseInt(String s) throws NumberFormatException;

異常類NumberFormatException屬於RuntimeException子類。使用parseInt()時可根據須要處理Runtime子類異常。

public class exception_RuntimeException{
    public static void main(String args[]){
        int temp = Integer.parseInt("100");
        System.out.println(temp);
    }
}

assert關鍵字

assert在JDK1.4時候引入的,一般用於程序不許備使用捕獲異常來處理的錯誤。其功能是在程序執行到某行後,判斷是不是預期的結果。斷言的語法格式:

assert 布爾表達式
assert 布爾表達式:字符串表達式

java默認沒有開啓斷言功能。所以程序正式執行時不用去除斷言語句。在執行解釋java字節碼文件時,增長參數「-ea」,開啓斷言功能。

java -ea exception_assert
public class exception_assert{
    public static void main(String args[]){
        int num = 10;
        assert num == 20 : "num isn't 20";
        System.out.println("num = " + num);
    }
}

自定義異常

當java提供的異常類型不能知足開發須要時,能夠本身開發一個異常類。實現自定義異常類,只須要繼承Exception或RuntimeException父類便可。

class AddException extends Exception{
    public AddException(String msg){
        super(msg);
    }
}
public class exception_selfdefine{
    public static void main(String args[]){
        int num = 20;
        try{
            if(num > 10){
                throw new AddException("value is too large!");
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

練習

填空
一、 Throwable下有哪兩個子類: 。
二、 ArthmeticException類表示 異常,ArraysIndexOutOfBoundsException表示 異常。
三、 一個try代碼後面必須跟着若干個 代碼段或者一個 代碼段。
四、 若是一個方法使用了 ,則編譯器會強制在使用此方法時進行異常的處理。
五、 異常處理中使用 做爲異常的統一出口。
選擇
一、 使用那個關鍵字能夠在程序中手工拋出異常 。

A、    throws            B、    throw            C、    assert        D、    class

二、 下面 關鍵字能夠用在方法的聲明處?

A、    throws            B、    assert            C、    class            D、    interface

三、 爲了捕獲一個異常,代碼必須放在下面 語句塊中。

A、    try塊            B、    catch塊            C、    throws塊        D、    finally塊

四、 下面關於try塊的說法正確的是 。

A、    try塊後至少應有一個catch塊            B、    try塊後必須有finally塊
C、    可能拋出異常的方法應放在try塊中        D、    對拋出的異常的處理應放在try塊中

五、 finally塊中的代碼將 。

A、    老是被執行
B、    若是try塊後面沒有catch塊時,finally塊中的代碼纔會執行
C、    異常發生時才被執行
D、    異常沒有發生時才執行

六、 一個異常將終止 。

A、    整個程序                        B、    只終止拋出異常的方法
C、    產生異常的try塊                D、    上面的說法都不對

七、 全部異常的共同父類是 。

A、    Error        B、    Exception        C、    Throwable        D、    RuntimeException

判斷一、 一個try語句後有多個catch時,捕獲範圍大的異常要放在捕獲範圍小的異常以後。 ( )二、 finally語句能夠根據須要有選擇的添加。 ( )簡答一、 簡述RuntimeException和Exception的區別。二、 try、catch、finally三種語句的功能是什麼?三、 簡述Java中的異常處理機制。四、 簡述Error和Exception的區別。五、 列舉三個常見的RuntimeException子類。編程一、 編寫應用程序,從命令行輸入兩個小數參數,求它們的商。要求程序中捕獲NumberFormatException異常和ArithmeticException異常。

相關文章
相關標籤/搜索