Java中的異常處理機制

Java中的異常處理機制

0x00異常

異常分為Error和Exception,我們通常說的處理異常,其實是處理Exception。而Error已經(jīng)不是異常了,而是錯誤。一般是因為代碼錯誤導致jvm崩潰。

用圖說話


異常大類

0x01 Exception類和它的子類

從上面的圖可以看到,Exception這個類下面有很多子類,他們都繼承自Exception,我們也可以自己寫一個異常類。例如:

public class MyException extends Exception {
}

然后就可以使用了,例如:

public static void throwException() throws MyException {
    throw new MyException();
}

原理會在下文講到

這個繼承于Exceptiion的類啥都沒寫,所以類里面的東西和Exception里面的是一樣的。讓我們來看看Exception里面有些什么。好吧。。。全是super.method,我們還是看它的父類Throwable吧。

private transient Object backtrace;
private String detailMessage;
private Throwable cause = this;

主要就是這三個。第一個,是在拋出Exception后的棧跟蹤。第二個,是異常詳情。第三個就是異常原因,就是異常本身。

異常的構(gòu)造方法:

public Exception();
public Exception(String message);
public Exception(String message, Throwable cause);
public Exception(Throwable cause);

我就不具體寫了。跟成員變量對應。

jvm通過棧來將異常一層一層往上拋(與一層一層的函數(shù)調(diào)用相反),直到他被處理(catch),否則,程序停止工作,jvm向用戶報告錯誤。異常的拋出(棧)路徑可以通過Exception.printStackTrace()方法查看
而異常被處理后,程序會回到拋出異常的地方繼續(xù)執(zhí)行。

0x02 如何拋出異常和進行異常處理

  • 拋出異常

    很簡單,直接使用throw關(guān)鍵字,但是如果拋出的異常未在當前方法處理,需要在方法后面聲明。需要在它所在的方法處聲明throws MyException。意思是此方法將拋出錯誤。

    注意:如果是RuntimeException或者它的子類的話,可以不附加聲明,例如:

    try {
        // some code
    } catch (RemoteException e) { 
        throw new RuntimeException(e);
    }
    
  • 處理異常

    使用try catch語句。用法:

    public static void main(String[] args) {
        try {
            throwException();
        } catch (MyException e) {
            e.printStackTrace();
            //Do sth...
            //throw e;
        }
    }
    

    try可能會拋出異常的語句塊,catch (MyException e)捕獲異常MyException聲明為引用e.一般來說都會跟上一個e.printStackTrace(),打印錯誤詳情,方便debug。
    當然你也可以再次將異常拋出,交給上層繼續(xù)處理。
    有人會發(fā)現(xiàn),e.printStackTrace()輸出的怎么是紅的,因為你看看它的源碼:

    public void printStackTrace() {
        printStackTrace(System.err);
    }
    

    它默認用的輸出流是System.err,而不是sout用的System.out哦。

  • 多重異常處理

    用于將不同類型的異常分開處理。

    try {
        throwException();
        throw new NullPointerException();
    } catch (MyException e) {
        e.printStackTrace();
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
    

對了,如果程序因異常而退出,它的返回值就不為0,在IDEA中可以明顯看到:Process finished with exit code xxx

0x03 finally關(guān)鍵字

你可能會遇到無論是否出現(xiàn)異常都需要進行某種操作的情況,這時候,你就需要用到finally了。比如:

try {
    throwException();
    throw new NullPointerException();
} catch (MyException e) {
    e.printStackTrace();
} catch (NullPointerException e) {
    e.printStackTrace();
}finally {
    System.out.println("An error occurred!");
}

這種方法經(jīng)常用來在異常發(fā)生后關(guān)閉流。
<del>其實可以把finally后面的語句看成擦屁股的</del>

0x04 異常丟失

這是一種特殊情況,雖然不經(jīng)常出現(xiàn),但是還是提一下比較好。

最簡單的觸發(fā)方法:

public static void main(String[] args) {
    try {
        throwException();
        throw new NullPointerException();
    } catch (MyException e) {
        e.printStackTrace();
    } catch (NullPointerException e) {
        e.printStackTrace();
    }finally {
        System.out.println("An error occurred!");
        return;
    }
}

也就是在finally里面執(zhí)行return。
IDEA里面會提示:

MissingException

其實原理就是在finally里面的語句會在異常處理完成之前執(zhí)行。如果在finnally里面return,就會發(fā)生異常丟失。

0x05 異常實例

private int take(int index, int last) {//取豆子
    int count;
    try {
        count = mPrisoners.get(index).take(index, last);
    } catch (Exception e) {//這些神經(jīng)病抓出來單獨死
        count = -1;
    }
    if (count > last || count < 0){//如果返回無效個數(shù),和上面的神經(jīng)病一樣死
        count = -1;
    }
    System.out.println(mPrisoners.get(index).getName() + "取了" + count + "個");
    //保存每個人取的豆子數(shù)
    mTempHold.replace(mPrisoners.get(index), count);
    return count;
}

取豆子游戲,源碼在這兒,Manager類。

這是異常處理的用法之一,你永遠不知道熊孩子們會搞出什么異常炸掉你的程序,所以熊孩子必須抓出來單獨死。

異常在Java中使用頻率極高,多次使用對異常自然就熟悉了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 大家好,我是IT修真院鄭州分院第6期的學員李亞衡,一枚正直純潔善良的JAVA程序員 今天給大家分享一下,修真院官網(wǎng)...
    一筒君閱讀 398評論 0 0
  • 通俗編程——白話JAVA異常機制 - 代碼之道,編程之法 - 博客頻道 - CSDN.NEThttp://blog...
    葡萄喃喃囈語閱讀 3,326評論 0 25
  • Java 中的異常處理機制:Java中的異常有兩大類:Error:系統(tǒng)錯誤,往往是 由軟件運行的硬件換件遭破壞所導...
    itachi閱讀 765評論 0 2
  • 先上圖 Java中所有的異常類都是繼承于Throwable的,表示可以拋出的對象。 Error(錯誤):是程序無法...
    yang2yang閱讀 282評論 0 0
  • 我感覺最深的一條是,我們在市場上所有用的東西都是自己實戰(zhàn)中總結(jié)出來的,不是來自于課本,不是來自于其他人的說教 當自...
    9135aa6a2ebe閱讀 410評論 0 0

友情鏈接更多精彩內(nèi)容