05.16 學習java異常處理機制個人的一些理解

學習java已經比較久一段時間了,其實對於java異常這方面的知識只停留在javac讓我throws一下或trycatch一下我就直接做了,其實並沒有真的瞭解整個java的異常處理機制是怎樣的,這幾天就深入的去了解了異常處理機制,下面我講一下對於java異常處理機制的一些個人的理解。

在講之前我先說一下學異常的時候我覺得異常處理沒什麼用的想法。看一些異常的講解,都說什麼除0異常,文件不存在異常。那時我心裡就在覺得挺奇怪的,既然有可能出現除0,那我加個判斷不就可以了?既然文件可能不存在,那我也加個判斷不就可以了?too young to simple

異常(Exception)

異常是什麼?不正常的事件。運行程序時,它沒有按照我們的預期執行,也就是不正常的運作,就叫異常。

首先

當我們寫java程序的時候,我們覺得這個地方可能會有異常(比如文件不存在),我們得怎麼做?1.要麼自己處理吧?(try、catch)2.要麼拋出去給調用者處理吧?(throws)

其次

當我們寫java程序的時候出現了異常,我們得知道異常的什麼? 1.是什麼異常得知道吧?(異常的分類) 2.異常出現在哪裡得知道吧?(異常鏈)

java解決上面需求的,就是我們所說的java異常處理機制

我將從以下方面講我所理解的java異常處理機制

1.異常類

2.異常處理語句及語法

3.異常鏈(異常棧)

4.常見異常

5.自定義異常

1.異常類

java中所有的事件、機制都由類描述,Java中的異常就是由java.lang包下的異常類描述的。

java異常類導圖

學習java異常處理機制個人的一些理解

Spring Cloud雲析 加群學習679819153

這是我根據java官方文檔用Xmind做的JDK8的異常類導圖,可以看出java的異常都是繼承Throwable父類的。

Throwable有派生出Error和Exception子類

Error:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it

A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur. That is, Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions.

以上兩段是官方文檔對Error類的解釋,簡單來說就是這些錯誤都是不能試圖去捕獲或拋出,因為這些錯誤是不能被程序員通過代碼去處理的,比如內存不足之類的,JVM本身錯誤等。Error類及其子類都是非檢查異常。

Exception:

The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.

The class Exception and any subclasses that are not also subclasses of RuntimeException are checked exceptions. Checked exceptions need to be declared in a method or constructor's throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary.

以上兩段也是官方文檔對Exception類的描述,大體上說就是可以讓程序員通過代碼去處理(try..catch / throws),並說明除了RuntimeException及其之類外的其他異常都是檢查異常。

上面提到的非檢查異常和檢查異常:

非檢查異常(unchecked exception):包括Error和RuntimeException以及他們的子類。java編譯器在編譯時,不會提示和發現這樣的異常,不要求在程序預處理這些異常(比如不會在寫程序時報小燈泡紅叉標識要你trycatch或者throws)。當然如果你覺得可能會有異常就可以使用try..catch處理或throws拋出。

檢查異常(checked exception):包括除了Error和RuntimeException的其他異常。java編譯器強制要求程序員預處理(通過報小燈泡紅叉要求你必須使用try..catch或throws)不然編譯器就會報錯不讓你通過。

一般的,作為程序員的我們應該關注Exception類下的分支的異常。

以上便是自己對java異常類的一些理解以及分類的講解。

2.異常處理語句及語法

在寫代碼處理異常的時候,有兩種不同的處理方式:1.使用try..catch..finally處理. 2.使用throws聲明拋給函數調用者去處理

1.try...catch..finally語句塊

學習java異常處理機制個人的一些理解

需要注意的是:

1.try塊發生異常,那麼try塊中發生異常的那一行以下的代碼都不會執行。

2.無論異常發生與否,異常是否有catch匹配處理,finally塊都會執行。

3.如果try..catch..中有return 先執行finally,再執行return

學習java異常處理機制個人的一些理解

Spring Cloud雲析 加群學習679819153

運行結果:

學習java異常處理機制個人的一些理解

Spring Cloud雲析 加群學習679819153

個人想法:catch塊中的異常類型,其實我覺得直接就一個Exception就好啦,什麼異常都直接捕獲,就不用再細分可能出現什麼異常了,一來代碼簡潔二來防止漏掉異常。

學習java異常處理機制個人的一些理解

throws是另一種異常處理的方式,作用是將函數中可能出現的異常拋給調用者來處理(向調用者聲明),自己不作處理。

一般使用throws有兩種原因:

1.方法本身不知道如何處理這樣的異常,或者說讓調用者處理更好,調用者需要為可能發生的異常負責。

2.分層思想:比如web開發的service和dao層,在大部分情況下,dao服務於service,但這都屬於開發組內部,所以,dao直接throw就可以了。但是到了service層,調用service的是另外的開發小組(比如客戶端小組),從架構上來說,就需要隱藏代碼的內部細節,這個時候就必須要catch掉。底層不處理,往上拋,上層去try catch然後去處理對應異常類型。再根據需求展示給用戶。

3.異常鏈(異常棧)

Java這種向上傳遞異常信息的處理機制,形成異常鏈。

異常鏈的概念我們用一段代碼來理解就好了

學習java異常處理機制個人的一些理解

運行結果:

學習java異常處理機制個人的一些理解

我寫了三個測試函數,除0異常出現在test3,然後test2調用test3,test1調用test2,main函數調用test1。

從異常結果可以看出main函數調用了test1發生了異常,把異常位置壓棧以此類推直到找出異常的真正位置,然後按棧先進後出依次輸出。

官方的說法就是Java方法拋出的可查異常將依據調用棧、沿著方法調用的層次結構一直傳遞到具備處理能力的調用方法,最高層次到main方法為止。

4.常見異常

看了下面的異常,是不是覺得很熟悉,很想打人哈哈哈。

1、 ArrayIndexOutOfBoundsException

數組索引越界異常。當對數組的索引值為負數或大於等於數組大小時拋出。

2、ArithmeticException

算術條件異常。譬如:整數除零等。

3、NullPointerException

空指針異常。當應用試圖在要求使用對象的地方使用了null時,拋出該異常。譬如:調用null對象的實例方法、訪問null對象的屬性、計算null對象的長度、使用throw語句拋出null等等

4、java.lang.ClassNotFoundException

找不到類異常。當應用試圖根據字符串形式的類名構造類,而在遍歷CLASSPAH之後找不到對應名稱的class文件就拋出該異常。

5、java.lang.NegativeArraySizeException 數組長度為負異常

6、java.lang.ArrayStoreException 數組中包含不兼容的值拋出的異常

7、java.lang.SecurityException 安全性異常

8、java.lang.IllegalArgumentException 非法參數異常

9、IOException:操作輸入流和輸出流時可能出現的異常。

10、EOFException 文件已結束異常

11、FileNotFoundException 文件未找到異常

12、ClassCastException 類型轉換異常類

13、ArrayStoreException 數組中包含不兼容的值拋出的異常

14、SQLException 操作數據庫異常類

15、NoSuchFieldException 字段未找到異常

16、NoSuchMethodException 方法未找到拋出的異常

17、NumberFormatException 字符串轉換為數字拋出的異常

18、StringIndexOutOfBoundsException 字符串索引超出範圍拋出的異常

19、IllegalAccessException 不允許訪問某類異常

20、InstantiationException 當應用程序試圖使用Class類中的newInstance()方法創建一個類的實例,而指定的類對象無法被實例化時,拋出該異常 Spring Cloud雲析 加群學習679819153

5.自定義異常

除了用java內置的異常類異常,我們還可以自定義自己所需要的異常。方法也很簡單

1.創建自己的異常類並寫自己的異常處理代碼

2.繼承Exception類(extends Exception)

3.在異常發生處的catch塊的異常類型中使用

學習java異常處理機制個人的一些理解

運行結果:自定義異常


分享到:


相關文章: