難度
初級
學習時間
30分鐘
適合人群
零基礎
開發語言
Java
開發環境
- JDK v11
- IntelliJ IDEA v2018.3
友情提示
- 本教學屬于系列教學,內容具有連貫性,本章使用到的內容之前教學中都有詳細講解。
- 本章內容針對零基礎或基礎較差的同學比較友好,可能對于有基礎的同學來說很簡單,希望大家可以根據自己的實際情況選擇繼續看完或等待看下一篇文章。謝謝大家的諒解!
1.異常體系
在Java異常這個大家族中,Throwable是這個異常家族中的老大,它下面有兩個靠譜老弟,一個叫“Error”,一個叫“Exception”。Error老弟負責錯誤部門,Exception老弟負責異常部門,它們各司其職。我給它們做了一個結構圖:

Throwable在上一章《“全棧2019”Java異常第十六章:Throwable詳解》中已經介紹過了,而Exception我們已經不陌生了,前面文章都和Exception有關,Error我們比較陌生一點,這一章章我們就著重講解它。
2.已檢查的異常
在上一章中,我們知道出于編譯時檢查異常的目的,Throwable和Throwable的任何子類(除Error和RuntimeException的子類)都被視為已檢查的異常。

Error不是已檢查的異常,那Error是什么呢?
Error是錯誤。
在Java異常體系中有三種異常:
第一種異常是已檢查的異常。
第二種異常是錯誤。
第三種異常是運行時異常。
已檢查的異常在上一章已經聊過了,現在我們來聊聊錯誤。運行時異常放在Exception的下一章講解。
3.錯誤

Error是Throwable的子類,表示合理的應用程序不應該嘗試捕獲的嚴重問題。當錯誤發生時,這些錯誤應該是無法預測或恢復的(try-catch或throws)。
當我們遇到Error時,我們不應該去使用try-catch捕獲它,也不應該throws將錯誤拋出去。
那該如何是好?
我們應該手動排查錯誤出現的原因及位置,然后把它解決在程序運行之前。
這里有一點非常重要,“當我們遇到Error時,我們不應該去使用try-catch捕獲它,也不應該throws將錯誤拋出去。”說的都是不應該,不是說不能。我們還是可以使用try-catch或throws,只是不應該這樣去做。
通俗來講就是,異常就像電腦打開某個軟件,然后軟件因為某個操作而崩潰了,這時你可以再重新打開一次軟件,這就相當于捕獲異常的操作修復好這個問題了;而錯誤就不一樣,錯誤就像你電腦冒煙了,這時你肯定是修不好了,也就相當于你無法捕獲這個錯誤去修復它。當然了,有小伙伴說電腦冒煙我能不能修復的試試?當然可以,這就和我們程序中遇到Error時,可以使用try-catch或者thorws,但是不建議你這么做。
我們來結合例子看看。
演示:
請拋出一個錯誤。
請觀察程序代碼及結果。
代碼:
Main類:

結果:

從運行結果來看,Error不是不能被try-catch的,而且不光可以try-catch程序還被修復好了,從運行結果我們就可以看出來:

那么我們程序本身做了什么呢?
首先,我們拋出一個Error對象,用來模擬制造一個錯誤:

緊接著,我們對其進行try-catch處理:

在catch中我們打印Error的堆棧跟蹤信息:

在try-catch的下面我們輸出了一段話,這行代碼的作用只有一個,那就是驗證我們的錯誤是被成功修復的:

程序執行結果也符合預期:

可能小伙伴們說,這例子也太技術含量了吧,是不是有點太敷衍我們了?
這個例子僅僅只是演示Error可以被try-catch,下面我們來一個實際開發中的案例,而且這個錯誤是日常開發中偶爾會碰到的。
4.內存溢出OutOfMemoryError
OutOfMemoryError對于大多數零基礎的同學來說,可能比較陌生,但是對于稍微有些開發經驗的同學來說,也算是打過幾次照面的。
OutOfMemoryError是什么?
OutOfMemoryError是內存溢出錯誤。
OutOfMemoryError什么時候會發生?
OutOfMemoryError在JVM(Java虛擬機)內存不足的情況下會發生。
大家還記得我們在講解《“全棧2019”Java異常第十三章:訪問異常堆棧跟蹤信息》一章中講到的JVM內存圖嗎?里面我們講到JVM會去申請一塊內存空間,這塊內存空間專門是用來存放Java應用數據的(比如基本數據類型、數組、對象...等等)。當這塊內存空間不足的時候,就會發生OutOfMemoryError異常。
來個例子演示一下。
演示:
請制造一個OutOfMemoryError異常。
請觀察程序代碼及結果。
代碼:
Main類:

結果:

從運行結果來看,我們程序的確是發生了OutOfMemoryError異常。接下來,我們看看它是怎么發生的。
程序代碼真的是好簡單,就一行:

我們創建了一個int類型的數組,只不過就是數組長度有點大,1024 * 1024 * 1024個長度。
為什么這一行代碼會產生OutOfMemoryError異常,讓JVM內存溢出?
因為我們在創建數組的時候,實際上就是在申請一塊內存空間用,這個內存空間就是數組的地盤,而且數組在申請內存空間的時候,還會按照數據類型的大小來預支實際內存大小,我們知道一個int占4個字節,我們申請了1024 * 1024 * 1024個int這么多的4個字節,可想而知內存申請有多大,所以創建一個長度超出JVM內存大小的數組時,就會產生OutOfMemoryError異常。
有的小伙伴的JVM內存可能有足夠大,所以當他運行和我一摸一摸的程序時,程序并沒有崩潰,那么請這樣的小伙伴再在數組長度的后面乘以1024。
為什么是1024?
因為1024在程序計算中容易換算,比如1KB=1024B(B:字節)。
像OutOfMemoryError我們就必要去捕獲它了,真發生了OutOfMemoryError程序就只能是崩潰之后重新運行。
為什么沒必要?
我們不知道它會什么時候出現,實際開發不像我們上面這樣去寫一個長度超出JVM內存大小的數組,內存的申請發生在每一行代碼身上,我不知道哪一行代碼運行時會造成OutOfMemoryError。
雖說沒必要,但是我們有沒有什么應對的措施?
有,實際開發中我們碰到OutOfMemoryError的時候就會去分析我們的程序代碼,找出那個產生OutOfMemoryError的源頭,修正程序。
總結
- Error是錯誤。它是Java異常體系中的一種。
- Error是Throwable的子類,表示合理的應用程序不應該嘗試捕獲的嚴重問題。
- 當我們遇到Error時,我們不應該去使用try-catch捕獲它,也不應該throws將錯誤拋出去。
- OutOfMemoryError是內存溢出錯誤。
- 實際開發中我們碰到OutOfMemoryError的時候就會去分析我們的程序代碼,找出那個產生OutOfMemoryError的源頭,修正程序。
至此,Java中Error相關內容講解先告一段落,更多內容請持續關注。
答疑
如果大家有問題或想了解更多前沿技術,請在下方留言或評論,我會為大家解答。
上一章
“全棧2019”Java異常第十六章:Throwable詳解
下一章
“全棧2019”Java異常第十八章:Exception詳解
學習小組
加入同步學習小組,共同交流與進步。
- 方式一:關注頭條號Gorhaf,私信“Java學習小組”。
- 方式二:關注公眾號Gorhaf,回復“Java學習小組”。
全棧工程師學習計劃
關注我們,加入“全棧工程師學習計劃”。

版權聲明
原創不易,未經允許不得轉載!