摘要:當(dāng)運(yùn)行時(shí)系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器,則運(yùn)行時(shí)系統(tǒng)終止。不可查異常編譯器不要求強(qiáng)制處置的異常包括運(yùn)行時(shí)異常與其子類和錯(cuò)誤。
目錄介紹
1.什么是異常
2.異常
2.1 異常的概述和分類【了解】
2.2 JVM默認(rèn)是如何處理異常的【理解】
2.3 異常處理的兩種方式【理解】
2.4 try...catch的方式處理異?!菊莆铡?/p>
2.5 編譯期異常和運(yùn)行期異常的區(qū)別【理解】
2.6 throw的概述以及和throws的區(qū)別【掌握】
2.7 異常的注意事項(xiàng)及如何使用異常處理【了解】
2.8 Throwable類中的常用方法
3.Error(錯(cuò)誤)
4.Exception(異常)
5.處理異常機(jī)制深入理解
5.1 拋出異常
5.2 捕獲異常
5.3 異常處理方式不同
6.異常總結(jié)
6.1 異??偨Y(jié)
6.2 try-catch-finally規(guī)則
6.3 try、catch、finally語句塊的執(zhí)行順序
6.4 Throws拋出異常的規(guī)則
7.自定義異常
好消息博客筆記大匯總【16年3月到至今】,包括Java基礎(chǔ)及深入知識點(diǎn),Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時(shí)開發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長期更新維護(hù)并且修正,持續(xù)完善……開源的文件是markdown格式的!同時(shí)也開源了生活博客,從12年起,積累共計(jì)47篇[近20萬字],轉(zhuǎn)載請注明出處,謝謝!
鏈接地址:https://github.com/yangchong2...
如果覺得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬事起于忽微,量變引起質(zhì)變!
0.異常思維導(dǎo)圖 1.什么是異常
1.1 什么是異常?
異常是正常程序流程所不能處理或者沒有處理的異常情況或異常事件,比如算術(shù)運(yùn)算被0除,數(shù)組下標(biāo)越界等。
Java采用try-catch-finally語句捕獲并處理異常并且處理異常。
1.2 finally一定會(huì)執(zhí)行嗎
finally是異常處理的統(tǒng)一出口,常用來實(shí)現(xiàn)資源釋放,比如關(guān)閉文件,關(guān)于數(shù)據(jù)庫連接等。除非遇到System.exit()強(qiáng)制退出程序外,finally語句塊無論是否發(fā)生異常都要執(zhí)行。
2.異常
2.1 異常的概述和分類
A:異常的概述: 異常就是Java程序在運(yùn)行過程中出現(xiàn)的錯(cuò)誤。
B:異常的分類:
C:異常的繼承體系
異常的基類: Throwable
嚴(yán)重問題: Error 不予處理,因?yàn)檫@種問題一般是很嚴(yán)重的問題,比如: 內(nèi)存溢出
非嚴(yán)重問題: Exception
編譯時(shí)異常: 非RuntimeException
運(yùn)行時(shí)異常: RuntimeException
2.2 JVM默認(rèn)是如何處理異常的【理解】
JVM默認(rèn)是如何處理異常的
main函數(shù)收到這個(gè)問題時(shí),有兩種處理方式:
a:自己將該問題處理,然后繼續(xù)運(yùn)行
b:自己沒有針對的處理方式,只有交給調(diào)用main的jvm來處理
jvm有一個(gè)默認(rèn)的異常處理機(jī)制,就將該異常進(jìn)行處理.
并將該異常的名稱,異常的信息.異常出現(xiàn)的位置打印在了控制臺(tái)上,同時(shí)將程序停止運(yùn)行
2.3 異常處理的兩種方式
try…catch…finally
throws
2.4 try...catch的方式處理異?!菊莆铡?/strong>
try...catch處理異常的基本格式
try { 可能出現(xiàn)問題的代碼 ; }catch(異常名 變量名){ 針對問題的處理 ; }finally{ 釋放資源; }
注意事項(xiàng):
a:try中的代碼越少越好
b:catch中要做處理,哪怕是一條輸出語句也可以.(不能將異常信息隱藏)
c:處理多個(gè)異常
1:能明確的盡量明確,不要用大的來處理。
2:平級關(guān)系的異常誰前誰后無所謂,如果出現(xiàn)了子父關(guān)系,父必須在后面。
2.5 編譯期異常和運(yùn)行期異常的區(qū)別【理解】
編譯期異常和運(yùn)行期異常的區(qū)別
Java中的異常被分為兩大類:編譯時(shí)異常和運(yùn)行時(shí)異常。
所有的RuntimeException類及其子類的實(shí)例被稱為運(yùn)行時(shí)異常,其他的異常就是編譯時(shí)異常
編譯時(shí)異常: Java程序必須顯示處理,否則程序就會(huì)發(fā)生錯(cuò)誤,無法通過編譯
運(yùn)行時(shí)異常: 無需顯示處理,也可以和編譯時(shí)異常一樣處理
2.6 throw的概述以及和throws的區(qū)別【掌握】
throws的方式處理異常: 定義功能方法時(shí),需要把出現(xiàn)的問題暴露出來讓調(diào)用者去處理。那么就通過throws在方法上標(biāo)識。
throw的概述: 在功能方法內(nèi)部出現(xiàn)某種情況,程序不能繼續(xù)運(yùn)行,需要進(jìn)行跳轉(zhuǎn)時(shí),就用throw把異常對象拋出。
a:throws
用在方法聲明后面,跟的是異常類名
可以跟多個(gè)異常類名,用逗號隔開
表示拋出異常,由該方法的調(diào)用者來處理
throws表示出現(xiàn)異常的一種可能性,并不一定會(huì)發(fā)生這些異常
static void pop() throws NegativeArraySizeException { // 定義方法并拋出NegativeArraySizeException異常 int[] arr = new int[-3]; // 創(chuàng)建數(shù)組 } public static void main(String[] args) { // 主方法 try { // try語句處理異常信息 pop(); // 調(diào)用pop()方法 } catch (NegativeArraySizeException e) { System.out.println("pop()方法拋出的異常");// 輸出異常信息 } } 使用throws關(guān)鍵字將異常拋給調(diào)用者后,如果調(diào)用者不想處理該異常,可以繼續(xù)向上拋出,但最終要有能夠處理該異常的調(diào)用者。 pop方法沒有處理異常NegativeArraySizeException,而是由main函數(shù)來處理。
b:throw
用在方法體內(nèi),跟的是異常對象名
只能拋出一個(gè)異常對象名
表示拋出異常,由方法體內(nèi)的語句處理
public PlayService getPlayService() { PlayService playService = BaseAppHelper.get().getPlayService(); if (playService == null) { //待解決:當(dāng)長期處于后臺(tái),如何保活?避免service被殺死…… throw new NullPointerException("play service is null"); } return playService; }
2.7 異常的注意事項(xiàng)及如何使用異常處理【了解】
A:異常注意事項(xiàng)(針對編譯期異常)
a:子類重寫父類方法時(shí),子類的方法必須拋出相同的異?;蚋割惍惓5淖宇悺?父親壞了,兒子不能比父親更壞)
b:如果父類拋出了多個(gè)異常,子類重寫父類時(shí),只能拋出相同的異?;蛘呤撬淖蛹?子類不能拋出父類沒有的異常
c:如果被重寫的方法沒有異常拋出,那么子類的方法絕對不可以拋出異常,如果子類方法內(nèi)有異常發(fā)生,那么子類只能try,不能throws
B:如何使用異常處理
原則:如果該功能內(nèi)部可以將問題處理,用try,如果處理不了,交由調(diào)用者處理,這是用throws
區(qū)別:
后續(xù)程序需要繼續(xù)運(yùn)行就try
后續(xù)程序不需要繼續(xù)運(yùn)行就throws
如果JDK沒有提供對應(yīng)的異常,需要自定義異常。
2.8 Throwable類中的常用方法
注意:catch關(guān)鍵字后面括號中的Exception類型的參數(shù)e。Exception就是try代碼塊傳遞給catch代碼塊的變量類型,e就是變量名。catch代碼塊中語句"e.getMessage();"用于輸出錯(cuò)誤性質(zhì)。通常異常處理常用3個(gè)函數(shù)來獲取異常的有關(guān)信息:
getCause():返回拋出異常的原因。如果 cause 不存在或未知,則返回 null。
getMeage():返回異常的消息信息。
printStackTrace():對象的堆棧跟蹤輸出至錯(cuò)誤輸出流,作為字段 System.err 的值。
有時(shí)為了簡單會(huì)忽略掉catch語句后的代碼,這樣try-catch語句就成了一種擺設(shè),一旦程序在運(yùn)行過程中出現(xiàn)了異常,就會(huì)忽略處理異常,而錯(cuò)誤發(fā)生的原因很難查找。
3.Error(錯(cuò)誤)Error(錯(cuò)誤):是程序無法處理的錯(cuò)誤,表示運(yùn)行應(yīng)用程序中較嚴(yán)重問題。大多數(shù)錯(cuò)誤與代碼編寫者執(zhí)行的操作無關(guān),而表示代碼運(yùn)行時(shí) JVM(Java 虛擬機(jī))出現(xiàn)的問題。例如,Java虛擬機(jī)運(yùn)行錯(cuò)誤(Virtual MachineError),當(dāng) JVM 不再有繼續(xù)執(zhí)行操作所需的內(nèi)存資源時(shí),將出現(xiàn) OutOfMemoryError。這些異常發(fā)生時(shí),Java虛擬機(jī)(JVM)一般會(huì)選擇線程終止。
4.Exception(異常)Exception(異常):是程序本身可以處理的異常。
Exception 這種異常分兩大類運(yùn)行時(shí)異常和非運(yùn)行時(shí)異常(編譯異常)。程序中應(yīng)當(dāng)盡可能去處理這些異常。
運(yùn)行時(shí)異常:都是RuntimeException類及其子類異常,如NullPointerException(空指針異常)、IndexOutOfBoundsException(下標(biāo)越界異常)等,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。這些異常一般是由程序邏輯錯(cuò)誤引起的,程序應(yīng)該從邏輯角度盡可能避免這類異常的發(fā)生。運(yùn)行時(shí)異常的特點(diǎn)是Java編譯器不會(huì)檢查它,也就是說,當(dāng)程序中可能出現(xiàn)這類異常,即使沒有用try-catch語句捕獲它,也沒有用throws子句聲明拋出它,也會(huì)編譯通過。
非運(yùn)行時(shí)異常 (編譯異常):是RuntimeException以外的異常,類型上都屬于Exception類及其子類。從程序語法角度講是必須進(jìn)行處理的異常,如果不處理,程序就不能編譯通過。如IOException、SQLException等以及用戶自定義的Exception異常,一般情況下不自定義檢查異常。
5.處理異常機(jī)制深入理解 5.1 拋出異常當(dāng)一個(gè)方法出現(xiàn)錯(cuò)誤引發(fā)異常時(shí),方法創(chuàng)建異常對象并交付運(yùn)行時(shí)系統(tǒng),異常對象中包含了異常類型和異常出現(xiàn)時(shí)的程序狀態(tài)等異常信息。運(yùn)行時(shí)系統(tǒng)負(fù)責(zé)尋找處置異常的代碼并執(zhí)行。
5.2 捕獲異常在方法拋出異常之后,運(yùn)行時(shí)系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器(exception handler)。潛在的異常處理器是異常發(fā)生時(shí)依次存留在調(diào)用棧中的方法的集合。當(dāng)異常處理器所能處理的異常類型與方法拋出的異常類型相符時(shí),即為合適 的異常處理器。運(yùn)行時(shí)系統(tǒng)從發(fā)生異常的方法開始,依次回查調(diào)用棧中的方法,直至找到含有合適異常處理器的方法并執(zhí)行。當(dāng)運(yùn)行時(shí)系統(tǒng)遍歷調(diào)用棧而未找到合適 的異常處理器,則運(yùn)行時(shí)系統(tǒng)終止。同時(shí),意味著Java程序的終止。
5.3 異常處理方式不同
Java的異常(包括Exception和Error)分為可查的異常(checked exceptions)和不可查的異常(unchecked exceptions)。
可查異常(編譯器要求必須處置的異常):正確的程序在運(yùn)行中,很容易出現(xiàn)的、情理可容的異常狀況??刹楫惓km然是異常狀況,但在一定程度上它的發(fā)生是可以預(yù)計(jì)的,而且一旦發(fā)生這種異常狀況,就必須采取某種方式進(jìn)行處理。除了RuntimeException及其子類以外,其他的Exception類及其子類都屬于可查異常。這種異常的特點(diǎn)是Java編譯器會(huì)檢查它,也就是說,當(dāng)程序中可能出現(xiàn)這類異常,要么用try-catch語句捕獲它,要么用throws子句聲明拋出它,否則編譯不會(huì)通過。
不可查異常(編譯器不要求強(qiáng)制處置的異常):包括運(yùn)行時(shí)異常(RuntimeException與其子類)和錯(cuò)誤(Error)。
總結(jié):一個(gè)方法所能捕捉的異常,一定是Java代碼在某處所拋出的異常。簡單地說,異常總是先被拋出,后被捕捉的。
處理運(yùn)行時(shí)異常
由于運(yùn)行時(shí)異常的不可查性,為了更合理、更容易地實(shí)現(xiàn)應(yīng)用程序,Java規(guī)定,運(yùn)行時(shí)異常將由Java運(yùn)行時(shí)系統(tǒng)自動(dòng)拋出,允許應(yīng)用程序忽略運(yùn)行時(shí)異常。
處理Error
對于方法運(yùn)行中可能出現(xiàn)的Error,當(dāng)運(yùn)行方法不欲捕捉時(shí),Java允許該方法不做任何拋出聲明。因?yàn)?,大多?shù)Error異常屬于永遠(yuǎn)不能被允許發(fā)生的狀況,也屬于合理的應(yīng)用程序不該捕捉的異常。
處理可查異常
對于所有的可查異常,Java規(guī)定:一個(gè)方法必須捕捉,或者聲明拋出方法之外。也就是說,當(dāng)一個(gè)方法選擇不捕捉可查異常時(shí),它必須聲明將拋出異常。
6.異常總結(jié) 6.1 異??偨Y(jié)try 塊:用于捕獲異常。其后可接零個(gè)或多個(gè)catch塊,如果沒有catch塊,則必須跟一個(gè)finally塊。 catch 塊:用于處理try捕獲到的異常。 finally 塊:無論是否捕獲或處理異常,finally塊里的語句都會(huì)被執(zhí)行。當(dāng)在try塊或catch塊中遇到return語句時(shí),finally語句塊將在方法返回之前被執(zhí)行。在以下4種特殊情況下,finally塊不會(huì)被執(zhí)行: 1)在finally語句塊中發(fā)生了異常。 2)在前面的代碼中用了System.exit()退出程序。 3)程序所在的線程死亡。 4)關(guān)閉CPU。6.2 try-catch-finally規(guī)則
1) 必須在 try 之后添加 catch 或 finally 塊。try 塊后可同時(shí)接 catch 和 finally 塊,但至少有一個(gè)塊。 2) 必須遵循塊順序:若代碼同時(shí)使用 catch 和 finally 塊,則必須將 catch 塊放在 try 塊之后。 3) catch 塊與相應(yīng)的異常類的類型相關(guān)。 4) 一個(gè) try 塊可能有多個(gè) catch 塊。若如此,則執(zhí)行第一個(gè)匹配塊。即Java虛擬機(jī)會(huì)把實(shí)際拋出的異常對象依次和各個(gè)catch代碼塊聲明的異常類型匹配,如果異常對象為某個(gè)異常類型或其子類的實(shí)例,就執(zhí)行這個(gè)catch代碼塊,不會(huì)再執(zhí)行其他的 catch代碼塊 5) 可嵌套 try-catch-finally 結(jié)構(gòu)。 6) 在 try-catch-finally 結(jié)構(gòu)中,可重新拋出異常。 7) 除了下列情況,總將執(zhí)行 finally 做為結(jié)束:JVM 過早終止(調(diào)用 System.exit(int));在 finally 塊中拋出一個(gè)未處理的異常;計(jì)算機(jī)斷電、失火、或遭遇病毒攻擊。6.3 try、catch、finally語句塊的執(zhí)行順序
1)當(dāng)try沒有捕獲到異常時(shí):try語句塊中的語句逐一被執(zhí)行,程序?qū)⑻^catch語句塊,執(zhí)行finally語句塊和其后的語句; 2)當(dāng)try捕獲到異常,catch語句塊里沒有處理此異常的情況:當(dāng)try語句塊里的某條語句出現(xiàn)異常時(shí),而沒有處理此異常的catch語句塊時(shí),此異常將會(huì)拋給JVM處理,finally語句塊里的語句還是會(huì)被執(zhí)行,但finally語句塊后的語句不會(huì)被執(zhí)行; 3)當(dāng)try捕獲到異常,catch語句塊里有處理此異常的情況:在try語句塊中是按照順序來執(zhí)行的,當(dāng)執(zhí)行到某一條語句出現(xiàn)異常時(shí),程序?qū)⑻絚atch語句塊,并與catch語句塊逐一匹配,找到與之對應(yīng)的處理程序,其他的catch語句塊將不會(huì)被執(zhí)行,而try語句塊中,出現(xiàn)異常之后的語句也不會(huì)被執(zhí)行,catch語句塊執(zhí)行完后,執(zhí)行finally語句塊里的語句,最后執(zhí)行finally語句塊后的語句;6.4 Throws拋出異常的規(guī)則
1) 如果是不可查異常(unchecked exception),即Error、RuntimeException或它們的子類,那么可以不使用throws關(guān)鍵字來聲明要拋出的異常,編譯仍能順利通過,但在運(yùn)行時(shí)會(huì)被系統(tǒng)拋出。 2)必須聲明方法可拋出的任何可查異常(checked exception)。即如果一個(gè)方法可能出現(xiàn)受可查異常,要么用try-catch語句捕獲,要么用throws子句聲明將它拋出,否則會(huì)導(dǎo)致編譯錯(cuò)誤 3)僅當(dāng)拋出了異常,該方法的調(diào)用者才必須處理或者重新拋出該異常。當(dāng)方法的調(diào)用者無力處理該異常的時(shí)候,應(yīng)該繼續(xù)拋出,而不是囫圇吞棗。 4)調(diào)用方法必須遵循任何可查異常的處理和聲明規(guī)則。若覆蓋一個(gè)方法,則不能聲明與覆蓋方法不同的異常。聲明的任何異常必須是被覆蓋方法所聲明異常的同類或子類。7.自定義異常
使用Java內(nèi)置的異常類可以描述在編程時(shí)出現(xiàn)的大部分異常情況。除此之外,用戶還可以自定義異常。用戶自定義異常類,只需繼承Exception類即可。
在程序中使用自定義異常類,大體可分為以下幾個(gè)步驟。
(1)創(chuàng)建自定義異常類。
(2)在方法中通過throw關(guān)鍵字拋出異常對象。
(3)如果在當(dāng)前拋出異常的方法中處理異常,可以使用try-catch語句捕獲并處理;否則在方法的聲明處通過throws關(guān)鍵字指明要拋出給方法調(diào)用者的異常,繼續(xù)進(jìn)行下一步操作。
(4)在出現(xiàn)異常方法的調(diào)用者中捕獲并處理異常。
關(guān)于其他內(nèi)容介紹 01.關(guān)于博客匯總鏈接1.技術(shù)博客匯總
2.開源項(xiàng)目匯總
3.生活博客匯總
4.喜馬拉雅音頻匯總
5.其他匯總
02.關(guān)于我的博客我的個(gè)人站點(diǎn):www.yczbj.org,www.ycbjie.cn
github:https://github.com/yangchong211
知乎:https://www.zhihu.com/people/...
簡書:http://www.jianshu.com/u/b7b2...
csdn:http://my.csdn.net/m0_37700275
喜馬拉雅聽書:http://www.ximalaya.com/zhubo...
開源中國:https://my.oschina.net/zbj161...
泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...
阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
segmentfault頭條:https://segmentfault.com/u/xi...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72030.html
摘要:再附一部分架構(gòu)面試視頻講解本文已被開源項(xiàng)目學(xué)習(xí)筆記總結(jié)移動(dòng)架構(gòu)視頻大廠面試真題項(xiàng)目實(shí)戰(zhàn)源碼收錄 Java反射(一)Java反射(二)Java反射(三)Java注解Java IO(一)Java IO(二)RandomAccessFileJava NIOJava異常詳解Java抽象類和接口的區(qū)別Java深拷貝和淺拷...
摘要:體現(xiàn)的就是適配器模式。數(shù)組對象集合世界中的機(jī)制機(jī)制集合世界中比較常見的錯(cuò)誤檢測機(jī)制,防止在對集合進(jìn)行遍歷過程當(dāng)中,出現(xiàn)意料之外的修改,會(huì)通過異常暴力的反應(yīng)出來。而在增強(qiáng)循環(huán)中,集合遍歷是通過進(jìn)行的。 前言 學(xué)習(xí)情況記錄 時(shí)間:week 2 SMART子目標(biāo) :Java 容器 記錄在學(xué)習(xí)Java容器 知識點(diǎn)中,關(guān)于List的重點(diǎn)知識點(diǎn)。 知識點(diǎn)概覽: 容器中的設(shè)計(jì)模式 從Array...
摘要:錯(cuò)誤上報(bào)機(jī)制發(fā)送數(shù)據(jù)因?yàn)檎埱蟊旧硪灿锌赡軙?huì)發(fā)生異常,而且有可能會(huì)引發(fā)跨域問題,一般情況下更推薦使用動(dòng)態(tài)創(chuàng)建標(biāo)簽的形式進(jìn)行上報(bào)。 js錯(cuò)誤捕獲 js錯(cuò)誤的實(shí)質(zhì),也是發(fā)出一個(gè)事件,處理他 error實(shí)例對象 對象屬性 message:錯(cuò)誤提示信息 name:錯(cuò)誤名稱(非標(biāo)準(zhǔn)屬性)宿主環(huán)境賦予 stack:錯(cuò)誤的堆棧(非標(biāo)準(zhǔn)屬性)宿主環(huán)境賦予 對象類型(7種) Synt...
摘要:請注意,我們在聊聊單元測試遇到問題多思考多查閱多驗(yàn)證,方能有所得,再勤快點(diǎn)樂于分享,才能寫出好文章。單元測試是指對軟件中的最小可測試單元進(jìn)行檢查和驗(yàn)證。 JAVA容器-自問自答學(xué)HashMap 這次我和大家一起學(xué)習(xí)HashMap,HashMap我們在工作中經(jīng)常會(huì)使用,而且面試中也很頻繁會(huì)問到,因?yàn)樗锩嫣N(yùn)含著很多知識點(diǎn),可以很好的考察個(gè)人基礎(chǔ)。但一個(gè)這么重要的東西,我為什么沒有在一開始...
閱讀 1947·2021-11-25 09:43
閱讀 1441·2021-11-22 14:56
閱讀 3306·2021-11-22 09:34
閱讀 2050·2021-11-15 11:37
閱讀 2324·2021-09-01 10:46
閱讀 1428·2019-08-30 15:44
閱讀 2323·2019-08-30 13:15
閱讀 2418·2019-08-29 13:07