Java異常學習總結

來源:互聯網
上載者:User

一、官方API對此的解釋: 

1、Throwable:異常和錯誤的基類,提供了錯誤堆棧實現等一系列方法。 兩個直接子類: Error & Exception

2、兩個子類區別:

     Error: 程式不應該捕捉的錯誤,應該交由JVM來處理。一般可能指非常重大的錯誤。

     Exception:程式中應該要捕獲的錯誤。

     RuntimeException:運行期異常,是Exception的子類,但勿需捕捉的異常超類

二、各自代碼中的表象  

Error & RuntimeException:不需要異常處理的,即無try/catch or throws的,編譯器認可此種方式;

Exception(排除RuntimeException):編譯器強制要求做異常處理的,即必須要 try/catch or throws的;

進一步解釋: Exception分為checked Exception & unchecked Exception兩種,

                  unchecked Exception指勿須檢查的異常,也即RuntimeException/Error,運行期錯誤JVM來打理;

                  checked Exception指必須處理的異常,否則編譯器就不讓過;

三、為何這樣設計?    

如上述,Throwable存在2種維度設計: 1、是否checked  2、 異常層級

是否checked: 表象很明顯,編譯器會強制檢測;

異常層級: 分為 錯誤和異常,可這個如何來區分呢?我確實很困惑,應該是個人理解的把握了。

四、異常常用關鍵點知識

1、保留異常源頭

    異常處理是層級追溯機制,因此異常可被多次拋出,但只要不改變源異常的控制代碼及其stackTrace,就可一直保留異常源頭。

    也即簡單的throw e(最初的那個異常),異常源頭依舊被保留。

2、改變異常源頭

    如果想改變異常源頭,通過拋出一個新異常或在層級機制處理中改變其stackTrace即可。

    如在調用方法中e.fillStackTrace() or throw new Excepiton("...")即可定位當前方法為異常源頭。

3、自訂異常

     一般來說,自訂異常多以checked的為主,也即從Exception繼承,實現非常簡單,複雜度就看業務需要了,就不多說了。

4、附上部分代碼,參照Thinking in java中的實現 

public class ThrowableExceptionStudy {        // 異常測試    public static void main(String[] args) throws InterruptedException {                reThrowTest();  // 異常重新拋出測試(可控制改變源頭)        rethrowNew();  // 拋出一個新異常測試(改變源頭)        runtimeExceptionTest(); // 運行期異常測試        errorTest();  // error測試    }        /**     * 異常重新拋出測試     */    private static void reThrowTest() {        try {            g();        } catch (Exception e) { // 拋出Exception            System.out.println("Caught exception in reThrowTest, e.printStackTrace()");            e.printStackTrace();        } catch    (Throwable t) { // 拋出Throwable            System.out.println("Caught throwable in reThrowTest, t.printStackTrace()");            t.printStackTrace();        }    }    /**     * 異常源頭     */    private static void f() throws Exception {        System.out.println("originating the exception in f()");        throw new Exception("thrown from f()");    }    /**     * 異常重新拋出,不改變異常控制代碼     * 以兩種方式拋出:1、不改變異常源頭 2、改變異常源頭     */    private static void g() throws Throwable {        try {            f();        } catch (Exception e) {            System.out.println("Inside g(), e.printStackTrace()");            e.printStackTrace();            //throw e; // a: 不改變異常源頭            throw e.fillInStackTrace(); // b:改變異常源頭, 通過fillInStatckTrace實現        }    }        /**     * 拋出一個新的異常,改變了異常控制代碼     */    private static void rethrowNew() {        try {            f();        } catch (Exception e) {            System.out.println("Caught in rethrowNew, e.printStackTrace()");            e.printStackTrace();            //throw new NullPointerException("from rethrowNew"); // RuntimeException,編譯器自動處理            try {                throw new Exception("from rethrowNew"); // 非RuntimeException,必須捕捉            } catch (Exception e1) {                e1.printStackTrace();            }        }    }    /**     * 運行期異常,勿須捕捉,編譯器會自動處理     */    private static void f1() {        throw new RuntimeException("From f1()");    }    /**     * 運行期異常測試     */    private static void runtimeExceptionTest() {        try{            f1();        } catch (RuntimeException e){            e.printStackTrace();        }    }        /**     * Error錯誤     */    private static void error() {        throw new Error("custome error,not exception. ");    }        /**     * Error測試     */    private static void errorTest(){        try{            error();        } catch (Error t){             t.printStackTrace();        }    }}

運行結果:

originating the exception in f()Inside g(), e.printStackTrace()java.lang.Exception: thrown from f()    at com.chq.study.ThrowableExceptionStudy.f(ThrowableExceptionStudy.java:40)    at com.chq.study.ThrowableExceptionStudy.g(ThrowableExceptionStudy.java:49)    at com.chq.study.ThrowableExceptionStudy.reThrowTest(ThrowableExceptionStudy.java:25)    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:14)Caught exception in reThrowTest, e.printStackTrace()java.lang.Exception: thrown from f()    at com.chq.study.ThrowableExceptionStudy.g(ThrowableExceptionStudy.java:54)    at com.chq.study.ThrowableExceptionStudy.reThrowTest(ThrowableExceptionStudy.java:25)    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:14)originating the exception in f()Caught in rethrowNew, e.printStackTrace()java.lang.Exception: thrown from f()    at com.chq.study.ThrowableExceptionStudy.f(ThrowableExceptionStudy.java:40)    at com.chq.study.ThrowableExceptionStudy.rethrowNew(ThrowableExceptionStudy.java:63)    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:15)java.lang.Exception: from rethrowNew    at com.chq.study.ThrowableExceptionStudy.rethrowNew(ThrowableExceptionStudy.java:69)    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:15)java.lang.RuntimeException: From f1()    at com.chq.study.ThrowableExceptionStudy.f1(ThrowableExceptionStudy.java:80)    at com.chq.study.ThrowableExceptionStudy.runtimeExceptionTest(ThrowableExceptionStudy.java:88)    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:16)java.lang.Error: custome error,not exception.     at com.chq.study.ThrowableExceptionStudy.error(ThrowableExceptionStudy.java:98)    at com.chq.study.ThrowableExceptionStudy.errorTest(ThrowableExceptionStudy.java:106)    at com.chq.study.ThrowableExceptionStudy.main(ThrowableExceptionStudy.java:17)

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.