java異常總結

java異常總結

#01 異常概述

異常分爲兩種

​ checked異常(JVM檢查時異常)

​ Runtime異常(運行時異常)

#02 異常處理機制

使用try…catch捕獲異常

​ try塊業務邏輯代碼出現異常,系統自動捕獲一個異常對象,提交給JVM,即拋出異常

​ catch塊中包含各種異常對象,執行第一個與try塊中相匹配的對象所對應的代碼塊,即捕獲異常

​ finally塊中進行資源回收,先finally後return,throw,如果出現System.exit(1)退出虛擬機,finally不會執行

使用throws拋出異常

​ 如果使用throws拋出給JVM(main方法上throws),JVM會打印異常的跟蹤棧信息,並終止程序運行

​ 拋出語法的格式爲:throws ExceptionClass1,ExceptionClass2,ExceptionClass3…

​ 異常拋出的"兩小"原則:自類方法聲明拋出的異常是父類異常的子類或相同,且數量不允許比父類多

異常類的繼承體系

​ Error錯誤:與虛擬機相關的問題,無法解決

​ AWTError,IOError,LinkageError,ThreadDeath

​ Exception:與程序相關的異常,可以捕獲或者拋出,根據異常的繼承關係,先處理子異常

​ CheckedException(檢查時異常):必須顯示的處理,try…catch或者throws

​ IOException

​ SQLException

​ RuntimeException(運行時異常):無需顯示處理,使用try…catch進行處理

​ indexOutOfBoundsException

​ NullPointerException

​ ClassCastException

多異常捕獲

​ 同一個catch塊捕獲多種異常,異常之間通過 | 隔開,異常變量有隱式的final修飾,不能對異常重新賦值

訪問異常信息

​ getMessage():返回該異常的詳細描述字符串

​ printStackTrace():將該異常的跟蹤棧信息輸出到標準錯誤輸出流

​ printStackTrace(PrintStream s):將該異常的跟蹤棧信息輸出到指定的輸出流

​ getStackTrace():返回該異常的跟蹤棧信息

public class TestTryCatch {
    public static void main(String[] args) {
        try{
            int[] a = {1,2,3};
            int i = a[5];
        }catch (Exception e){
            e.printStackTrace();
            System.out.println();
       
            System.out.println(e);

            String message = e.getMessage();
            System.out.println(message);

            StackTraceElement[] stackTrace = e.getStackTrace();
            System.out.println(stackTrace);
        }
    }
}
輸出結果爲:
	java.lang.ArrayIndexOutOfBoundsException: 5
	at TestTryCatch.main(TestTryCatch.java:5)

java.lang.ArrayIndexOutOfBoundsException: 5
5
[Ljava.lang.StackTraceElement;@610455d6

異常處理嵌套

​ 在try塊,catch塊或者finally塊中包含完整的異常處理流程的情形被稱爲異常處理的嵌套,不建議超過兩層

特例——Java7種自動關閉資源的try語句

​ try(聲明或者初始化一個或多個必須在程序結束時關閉的資源類 ){}

​ 這些資源類必須實現AutoCloseable接口或者Closeable接口,資源類在java7中包括IO的各種類,JDBC編程的Connection,Statement等接口

#03 使用throw拋出異常

拋出異常

​ 異常是主觀說法,是否需要拋出異常,需要根據應用的業務需求來決定

​ 使用throw拋出一個異常實例而不是異常類 throw ExceptionInstance;

​ Checked Exception Instance:需要顯示捕獲該異常並作處理

​ RuntimeException:可以不理會,講給方法調用者處理

自定義異常

​ 自定義異常應該繼承Exception基類(檢查時異常)或者RuntimeException基類(運行時異常),同時提供兩個構造器,一個是無參構造,一個是以字符串爲參數(該異常對象的描述信息,getMessage()返回的值))的構造

同時使用catch和throw

​ 多個方法同時處理一個異常的情況——在catch塊中結合throw語句

​ 企業級應用對異常的處理:1、應用後臺需要通過日誌來記錄異常發生的詳細信息 2、應用還需要根據異常想應用使用者傳達某種提示

異常鏈

​ 捕獲原始異常,拋出新的業務異常——異常轉義

​ 捕獲一個異常,接着拋出另一個異常,並把原始異常信息保存下來的鏈式處理成爲異常鏈

![image-20190601161709482](/Users/jiang.li/Library/Application Support/typora-user-images/image-20190601161709482.png)

#04 java異常跟蹤棧

​ 異常只要沒有被完全捕獲(包括異常沒有被捕獲,或異常被處理後重新拋出了新的異常),異常從發生異常的方法逐漸向外傳播,首先傳給該方法的調用者,逐次向上,直至main方法,main()沒有處理JVM則會終止程序,並打印棧信息

java.lang.RuntimeException: level 2 exception
	at com.msh.demo.exceptionStack.Test.fun2(Test.java:17)
	at com.msh.demo.exceptionStack.Test.main(Test.java:24)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.io.IOException: level 1 exception
  at com.msh.demo.exceptionStack.Test.fun1(Test.java:10)
  at com.msh.demo.exceptionStack.Test.fun2(Test.java:15)
  ... 6 more

第一行信息顯示了異常的類型和詳細信息

跟蹤棧記錄了程序中所有異常發生點,各行顯示被調用方法中執行的停止位置,並標明類、類中的方法名,與故障點對應的文件的行。

跟蹤棧總是最內部的被調用方法逐漸上傳,直到最外部業務操作的起點,通常就是程序的入口main方法或Thread類的run方法

#05 異常處理規則

不要過度使用異常

​ 對於普通的錯誤,應該編寫處理這中錯誤的代碼,增加程序的健壯性,只有對外部的,不能確定和預測的運行時錯誤才使用異常。

​ 異常機制的效率比正常的流程控制效率差

不要使用過於龐大的try塊

避免使用Catch All

不要忽略捕獲到的異常

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