JavaSE詳細(xì)講解異常語(yǔ)法
1.異常的概念
Java中將程序執(zhí)行過程中發(fā)生的不正常的行為稱為異常
比較常見的異常如下:


2.異常的體系結(jié)構(gòu)
Throwable:是異常體系的最頂層的類,它有兩個(gè)重要的子類,:Error 和 Exception
Exception:我們經(jīng)常說(shuō)的異常就是Exception,此類問題可以通過代碼進(jìn)行處理從而使程序可以繼續(xù)往下運(yùn)行
Error:指的是Java虛擬機(jī)無(wú)法解決的嚴(yán)重問題,這類問題就比較嚴(yán)重了,一旦發(fā)生想要挽回就很困難了,就像人得了不治之癥
異常體系的結(jié)構(gòu)圖大致如下:

異常根據(jù)發(fā)生的時(shí)機(jī)不同分為編譯時(shí)異常(受檢查異常)和運(yùn)行時(shí)異常(非受檢查異常)
RuntimeException以及其子類對(duì)應(yīng)的異常都是運(yùn)行時(shí)異常
注:寫代碼的時(shí)候出現(xiàn)的語(yǔ)法錯(cuò)誤不能稱之為異常
3.異常的處理
處理異常的兩個(gè)思想:
LBYL:在操作之前進(jìn)行充分的檢查
EAFP:先進(jìn)行操作,在遇到問題的時(shí)候再來(lái)處理
異常處理的核心思想就是EAFP
3.1拋出異常
首先可定是要找出異常的位置
關(guān)鍵字:throw
語(yǔ)法如下;
throw new xxxException("產(chǎn)生異常的原因")
比如寫一個(gè)獲取數(shù)組元素的方法
public static int getElement(int[] arr,int index) {
if(arr==null) {
throw new NullPointerException("數(shù)組為空");
}
if(index<0||index>=arr.length) {
throw new ArrayIndexOutOfBoundsException("下標(biāo)非法");
}
return arr[index];
}

注:
- throw必須是在方法內(nèi)部
- 拋出的對(duì)象必須是Exception類或者其子類對(duì)象
- 如果拋出的是RuntimeException類或者其子類(即運(yùn)行時(shí)異常),可以交給JVM處理
- 如果拋出的是編譯時(shí)異常,需要自己處理,否則代碼無(wú)法通過編譯
- 異常一旦拋出,后面的代碼便不會(huì)再執(zhí)行
3.2處理異常
主要有兩種方式throws和try-catch
3.2.1throws
throws是聲明異常,當(dāng)方法拋出編譯時(shí)異常時(shí)使用throws將異常拋給方法的調(diào)用者來(lái)處理。即當(dāng)前方法不處理異常,提醒方法的調(diào)用者處理異常
語(yǔ)法如下:
方法返回值 方法名() throws 異常類型1,異常類型2{......}
之前文章介紹對(duì)象進(jìn)行比較和克隆操作常用的接口的時(shí)候有出現(xiàn)過這種用法
原文鏈接抽象類和接口
使用注意:
- throws位置是在方法的參數(shù)列表后
- 聲明的異常必須是Exception類或者其子類
- throws后面可以有多個(gè)異常,中間用逗號(hào)隔開即可,如果是有父子關(guān)系的,聲明父類即可
- 調(diào)用聲明拋出異常的方法時(shí),調(diào)用者必須對(duì)該異常進(jìn)行處理,或者繼續(xù)使用throws拋出
throw和throws很相像,二者之間的區(qū)別需要注意
| throw | throws |
在方法內(nèi)使用 | 跟在方法聲明后面 |
一個(gè)throw只能拋出一個(gè)異常 | 后面可以跟多個(gè)異常類名 |
拋出的異常由方法內(nèi)的語(yǔ)句處理 | 拋出的異常由方法的調(diào)用者處理 |
執(zhí)行throw是一定出現(xiàn)了某種異常 | 表示有出現(xiàn)異常的可能性,并不一定就會(huì)出現(xiàn)這些異常 |
3.2.2try-catch
try-catch就是真正的對(duì)異常進(jìn)行處理,語(yǔ)法如下:
try {
//可能出現(xiàn)異常的代碼放在此處
} catch(xxxException e) {
//若try拋出的異常被catch捕獲到,在此處進(jìn)行處理
}try后面可以有多個(gè)catch,catch括號(hào)中可以寫多個(gè)異常類型,中間使用“|”隔開
還是以上面的獲取數(shù)組元素的方法為例,對(duì)其進(jìn)行修改:
public static int getElement(int[] arr,int index) {
return arr[index];
}
//main方法中使用try-catch
public static void main(String[] args) {
int[] arr=new int[]{1,2,3,4,5};
try {
getElement(null,1);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("下標(biāo)越界");
} catch(NullPointerException e) {
System.out.println("空數(shù)組");
}
}
注意:
try塊內(nèi)拋出異常位置之后的代碼不會(huì)被執(zhí)行

try拋出的異常需要被catch捕獲才能處理,如果拋出的異常沒有被捕獲,則會(huì)繼續(xù)向外拋出,直至JVM中斷程序
如果異常之間具有父子關(guān)系,一定是子類異常在前先被捕獲,父類異常后被捕獲
使用try-catch后只會(huì)打印自己代碼塊內(nèi)的信息,上圖中也可以看到,想要異常信息盡可能完整,可使用printStackTrace()方法

此外還有一個(gè)關(guān)鍵字:finally
這個(gè)關(guān)鍵字需要記住的是:不管程序是否發(fā)生異常,finally中的語(yǔ)句都會(huì)被執(zhí)行
基于此特點(diǎn),所以finally一般是用來(lái)進(jìn)行一些資源清理的掃尾工作
還有,不建議在finally中放入return語(yǔ)句,比如下面代碼
public static int fc() {
try {
retrun 1;
} catch(ArithmeticException e) {
System.out.println("算數(shù)異常");
} finally {
return 10;
}
}結(jié)果返回的是10,try中的1因?yàn)閒ianlly的存在是無(wú)法返回的
3.3異常的處理流程
在JVM中有一塊內(nèi)存空間叫做"虛擬機(jī)棧" ,這塊空間是專門用來(lái)存儲(chǔ)方法之間的調(diào)用關(guān)系的,這種調(diào)用關(guān)系用“調(diào)用棧”來(lái)描述
當(dāng)代碼中出現(xiàn)異常而又沒有對(duì)應(yīng)的處理方式的時(shí)候,就會(huì)沿著調(diào)用棧向上傳遞,直到傳遞到JVM終止程序
異常的處理流程如下:
- 優(yōu)先執(zhí)行try中的代碼拋出異常
- 若catch捕獲到異常,則處理異常,否則向上傳遞
- 如果一直到 main 方法也沒有合適的代碼處理異常, 就會(huì)交給 JVM 來(lái)進(jìn)行處理, 此時(shí)程序就會(huì)異常終止
4.自定義異常
雖然Java本身就已經(jīng)有很多異常類,但在實(shí)際的開發(fā)中仍然會(huì)遇到一些Java中沒有包含的異常,此時(shí)就需要自定義異常
具體實(shí)現(xiàn)方式如下:
- 自定義一個(gè)類,繼承Exception(編譯時(shí)異常)或RunTimeException(運(yùn)行時(shí)異常)
- 類里面實(shí)現(xiàn)一個(gè)帶有String類型參數(shù)的構(gòu)造方法,String是為了說(shuō)明出現(xiàn)異常的原因
到此這篇關(guān)于JavaSE詳細(xì)講解異常語(yǔ)法的文章就介紹到這了,更多相關(guān)Java異常內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java concurrency之公平鎖(一)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java concurrency之公平鎖的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
SpringCloud網(wǎng)關(guān)Gateway架構(gòu)解析
這篇文章主要介紹了SpringCloud網(wǎng)關(guān)Gateway架構(gòu)解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
SpringBoot實(shí)現(xiàn)發(fā)送郵件功能過程圖解
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)發(fā)送郵件功能過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03

