Java中的異常處理(try,catch,finally,throw,throws)
前言:
Java異常處理的五個(gè)關(guān)鍵字:try、catch、finally、throw、throws
拋出異常throw
在編寫(xiě)程序時(shí),我們必須要考慮程序出現(xiàn)問(wèn)題的情況。比如,在定義方法時(shí),方法需要接受參數(shù)。那么,當(dāng)調(diào)用方法使用接受到的參數(shù)時(shí),首先需要先對(duì)參數(shù)數(shù)據(jù)進(jìn)行合法的判斷,數(shù)據(jù)若不合法,就應(yīng)該告訴調(diào)用者,傳遞合法的數(shù)據(jù)進(jìn)來(lái)。這時(shí)需要使用拋出異常的方式來(lái)告訴調(diào)用者。 在java中,提供了一個(gè)throw關(guān)鍵字,它用來(lái)拋出一個(gè)指定的異常對(duì)象。那么,拋出一個(gè)異常具體如何操作呢???
- 創(chuàng)建一個(gè)異常對(duì)象。封裝一些提示信息(信息可以自己編寫(xiě))。
- 需要將這個(gè)異常對(duì)象告知給調(diào)用者。怎么告知呢?怎么將這個(gè)異常對(duì)象傳遞到調(diào)用者處呢?通過(guò)關(guān)鍵字throw就可以完成。throw 異常對(duì)象。
throw用在方法內(nèi),用來(lái)拋出一個(gè)異常對(duì)象,將這個(gè)異常對(duì)象傳遞到調(diào)用者處,并結(jié)束當(dāng)前方法的執(zhí)行。
使用格式:
throw new 異常類(lèi)名(參數(shù));
例如:
throw new NullPointerException("要訪問(wèn)的arr數(shù)組不存在"); throw new ArrayIndexOutOfBoundsException("該索引在數(shù)組中不存在,已超出范圍");
學(xué)習(xí)完拋出異常的格式后,我們通過(guò)下面程序演示下throw的使用。
public class ThrowDemo { public static void main(String[] args) { //創(chuàng)建一個(gè)數(shù)組 int[] arr = {2,4,52,2}; //根據(jù)索引找對(duì)應(yīng)的元素 int index = 4; int element = getElement(arr, index); System.out.println(element); System.out.println("over"); } /* * 根據(jù) 索引找到數(shù)組中對(duì)應(yīng)的元素 */ public static int getElement(int[] arr,int index){ //判斷 索引是否越界 if(index<0 || index>arr.length-1){ /* 判斷條件如果滿足,當(dāng)執(zhí)行完throw拋出異常對(duì)象后,方法已經(jīng)無(wú)法繼續(xù)運(yùn)算。 這時(shí)就會(huì)結(jié)束當(dāng)前方法的執(zhí)行,并將異常告知給調(diào)用者。這時(shí)就需要通過(guò)異常來(lái)解決。 */ throw new ArrayIndexOutOfBoundsException("哥們,數(shù)組越界了```"); } int element = arr[index]; return element; } }
注意:如果產(chǎn)生了問(wèn)題,我們就會(huì)throw將問(wèn)題描述類(lèi)即異常進(jìn)行拋出,也就是將問(wèn)題返回給該方法的調(diào)用者。 那么對(duì)于調(diào)用者來(lái)說(shuō),該怎么處理呢?一種是進(jìn)行捕獲處理,另一種就是繼續(xù)講問(wèn)題聲明出去,使用throws聲明處理。
Objects非空判斷
還記得我們學(xué)習(xí)過(guò)一個(gè)類(lèi)Objects嗎,曾經(jīng)提到過(guò)它由一些靜態(tài)的實(shí)用方法組成,這些方法是null-save(空指針安全的)或null-tolerant(容忍空指針的),那么在它的源碼中,對(duì)對(duì)象為null的值進(jìn)行了拋出異常操作。
public static <T> T requireNonNull(T obj)
:查看指定引用對(duì)象不是null。
查看源碼發(fā)現(xiàn)這里對(duì)為null的進(jìn)行了拋出異常操作:
public static <T> T requireNonNull(T obj) { if (obj == null) throw new NullPointerException(); return obj; }
聲明異常throws
聲明異常:將問(wèn)題標(biāo)識(shí)出來(lái),報(bào)告給調(diào)用者。如果方法內(nèi)通過(guò)throw拋出了編譯時(shí)異常,而沒(méi)有捕獲處理(稍后講解該方式),那么必須通過(guò)throws進(jìn)行聲明,讓調(diào)用者去處理。 關(guān)鍵字throws運(yùn)用于方法聲明之上,用于表示當(dāng)前方法不處理異常,而是提醒該方法的調(diào)用者來(lái)處理異常(拋出異常). 聲明異常格式:
修飾符 返回值類(lèi)型 方法名(參數(shù)) throws 異常類(lèi)名1,異常類(lèi)名2…{ }
聲明異常的代碼演示:
public class ThrowsDemo { public static void main(String[] args) throws FileNotFoundException { read("a.txt"); } // 如果定義功能時(shí)有問(wèn)題發(fā)生需要報(bào)告給調(diào)用者??梢酝ㄟ^(guò)在方法上使用throws關(guān)鍵字進(jìn)行聲明 public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) {//如果不是 a.txt這個(gè)文件 // 我假設(shè) 如果不是 a.txt 認(rèn)為 該文件不存在 是一個(gè)錯(cuò)誤 也就是異常 throw throw new FileNotFoundException("文件不存在"); } } }
throws用于進(jìn)行異常類(lèi)的聲明,若該方法可能有多種異常情況產(chǎn)生,那么在throws后面可以寫(xiě)多個(gè)異常類(lèi),用逗號(hào)隔開(kāi)。
public class ThrowsDemo2 { public static void main(String[] args) throws IOException { read("a.txt"); } public static void read(String path)throws FileNotFoundException, IOException { if (!path.equals("a.txt")) {//如果不是 a.txt這個(gè)文件 // 我假設(shè) 如果不是 a.txt 認(rèn)為 該文件不存在 是一個(gè)錯(cuò)誤 也就是異常 throw throw new FileNotFoundException("文件不存在"); } if (!path.equals("b.txt")) { throw new IOException(); } } }
捕獲異常try…catch
如果異常出現(xiàn)的話,會(huì)立刻終止程序,所以我們得處理異常:
- 該方法不處理,而是聲明拋出,由該方法的調(diào)用者來(lái)處理(throws)。
- 在方法中使用try-catch的語(yǔ)句塊來(lái)處理異常。
try-catch的方式就是捕獲異常。
- 捕獲異常:Java中對(duì)異常有針對(duì)性的語(yǔ)句進(jìn)行捕獲,可以對(duì)出現(xiàn)的異常進(jìn)行指定方式的處理。
捕獲異常語(yǔ)法如下:
try{ 編寫(xiě)可能會(huì)出現(xiàn)異常的代碼 }catch(異常類(lèi)型 e){ 處理異常的代碼 //記錄日志/打印異常信息/繼續(xù)拋出異常 }
**try:**該代碼塊中編寫(xiě)可能產(chǎn)生異常的代碼。 **catch:**用來(lái)進(jìn)行某種異常的捕獲,實(shí)現(xiàn)對(duì)捕獲到的異常進(jìn)行處理。
注意:try和catch都不能單獨(dú)使用,必須連用。
演示如下:
public class TryCatchDemo { public static void main(String[] args) { try {// 當(dāng)產(chǎn)生異常時(shí),必須有處理方式。要么捕獲,要么聲明。 read("b.txt"); } catch (FileNotFoundException e) {// 括號(hào)中需要定義什么呢? //try中拋出的是什么異常,在括號(hào)中就定義什么異常類(lèi)型 System.out.println(e); } System.out.println("over"); } /* * * 我們 當(dāng)前的這個(gè)方法中 有異常 有編譯期異常 */ public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) {//如果不是 a.txt這個(gè)文件 // 我假設(shè) 如果不是 a.txt 認(rèn)為 該文件不存在 是一個(gè)錯(cuò)誤 也就是異常 throw throw new FileNotFoundException("文件不存在"); } } }
如何獲取異常信息: Throwable類(lèi)中定義了一些查看方法:
public String getMessage()
:獲取異常的描述信息,原因(提示給用戶(hù)的時(shí)候,就提示錯(cuò)誤原因。public String toString()
:獲取異常的類(lèi)型和異常描述信息(不用)。public void printStackTrace()
:打印異常的跟蹤棧信息并輸出到控制臺(tái)。
包含了異常的類(lèi)型,異常的原因,還包括異常出現(xiàn)的位置,在開(kāi)發(fā)和調(diào)試階段,都得使用printStackTrace。
finally 代碼塊
finally:有一些特定的代碼無(wú)論異常是否發(fā)生,都需要執(zhí)行。另外,因?yàn)楫惓?huì)引發(fā)程序跳轉(zhuǎn),導(dǎo)致有些語(yǔ)句執(zhí)行不到。而finally就是解決這個(gè)問(wèn)題的,在finally代碼塊中存放的代碼都是一定會(huì)被執(zhí)行的。 什么時(shí)候的代碼必須最終執(zhí)行??? 當(dāng)我們?cè)趖ry語(yǔ)句塊中打開(kāi)了一些物理資源(磁盤(pán)文件/網(wǎng)絡(luò)連接/數(shù)據(jù)庫(kù)連接等),我們都得在使用完之后,最終關(guān)閉打開(kāi)的資源。 finally的語(yǔ)法: try...catch....finally:自身需要處理異常,最終還得關(guān)閉資源。
注意:finally不能單獨(dú)使用。
比如在IO流中,當(dāng)打開(kāi)了一個(gè)關(guān)聯(lián)文件的資源,最后程序不管結(jié)果如何,都需要把這個(gè)資源關(guān)閉掉。 finally代碼參考如下:
public class TryCatchDemo4 { public static void main(String[] args) { try { read("a.txt"); } catch (FileNotFoundException e) { //抓取到的是編譯期異常 拋出去的是運(yùn)行期 throw new RuntimeException(e); } finally { System.out.println("不管程序怎樣,這里都將會(huì)被執(zhí)行。"); } System.out.println("over"); } /* * * 我們 當(dāng)前的這個(gè)方法中 有異常 有編譯期異常 */ public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) {//如果不是 a.txt這個(gè)文件 // 我假設(shè) 如果不是 a.txt 認(rèn)為 該文件不存在 是一個(gè)錯(cuò)誤 也就是異常 throw throw new FileNotFoundException("文件不存在"); } } }
當(dāng)只有在try或者catch中調(diào)用退出JVM的相關(guān)方法,此時(shí)finally才不會(huì)執(zhí)行,否則finally永遠(yuǎn)會(huì)執(zhí)行。
異常注意事項(xiàng)
多個(gè)異常使用捕獲又該如何處理呢?
- 多個(gè)異常分別處理。
- 多個(gè)異常一次捕獲,多次處理。
- 多個(gè)異常一次捕獲一次處理。
一般我們是使用一次捕獲多次處理方式,格式如下:
try{ 編寫(xiě)可能會(huì)出現(xiàn)異常的代碼 }catch(異常類(lèi)型A e){ 當(dāng)try中出現(xiàn)A類(lèi)型異常,就用該catch來(lái)捕獲. 處理異常的代碼 //記錄日志/打印異常信息/繼續(xù)拋出異常 }catch(異常類(lèi)型B e){ 當(dāng)try中出現(xiàn)B類(lèi)型異常,就用該catch來(lái)捕獲. 處理異常的代碼 //記錄日志/打印異常信息/繼續(xù)拋出異常 }
注意:這種異常處理方式,要求多個(gè)catch中的異常不能相同,并且若catch中的多個(gè)異常之間有子父類(lèi)異常的關(guān)系,那么子類(lèi)異常要求在上面的catch處理,父類(lèi)異常在下面的catch處理。
- 運(yùn)行時(shí)異常被拋出可以不處理。即不捕獲也不聲明拋出。
- 如果finally有return語(yǔ)句,永遠(yuǎn)返回finally中的結(jié)果,避免該情況.
- 如果父類(lèi)拋出了多個(gè)異常,子類(lèi)重寫(xiě)父類(lèi)方法時(shí),拋出和父類(lèi)相同的異?;蛘呤歉割?lèi)異常的子類(lèi)或者不拋出異常。
- 父類(lèi)方法沒(méi)有拋出異常,子類(lèi)重寫(xiě)父類(lèi)該方法時(shí)也不可拋出異常。此時(shí)子類(lèi)產(chǎn)生該異常,只能捕獲處理,不能聲明拋出。
到此這篇關(guān)于Java中的異常處理(try,catch,finally,throw,throws)的文章就介紹到這了,更多相關(guān)Java異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
String與Blob互轉(zhuǎn)和file文件與Blob互轉(zhuǎn)方式
這篇文章主要介紹了String與Blob互轉(zhuǎn)和file文件與Blob互轉(zhuǎn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05如何基于Spring使用工廠模式實(shí)現(xiàn)程序解耦
這篇文章主要介紹了如何基于Spring使用工廠模式實(shí)現(xiàn)程序解耦,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12在Action中以Struts2的方式輸出JSON數(shù)據(jù)的實(shí)例
下面小編就為大家?guī)?lái)一篇在Action中以Struts2的方式輸出JSON數(shù)據(jù)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11java 中 阻塞隊(duì)列BlockingQueue詳解及實(shí)例
這篇文章主要介紹了java 中 阻塞隊(duì)列BlockingQueue詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03Spring中ContextLoaderListener監(jiān)聽(tīng)詳解
這篇文章主要介紹了Spring中ContextLoaderListener監(jiān)聽(tīng)詳解,SpringMVC啟動(dòng)時(shí)會(huì)啟動(dòng)WebApplicationContext類(lèi)型的容器,并且會(huì)調(diào)用之前分析的refresh方法,需要的朋友可以參考下2024-01-01java實(shí)現(xiàn)的密碼強(qiáng)度檢測(cè)功能完整示例
這篇文章主要介紹了java實(shí)現(xiàn)的密碼強(qiáng)度檢測(cè)功能,結(jié)合完整實(shí)例形式分析了java針對(duì)密碼強(qiáng)度檢測(cè)相關(guān)的字符串遍歷、判斷,以及輸出密碼強(qiáng)度等級(jí)相關(guān)操作技巧,需要的朋友可以參考下2019-06-06Spring Boot Actuator未授權(quán)訪問(wèn)漏洞的問(wèn)題解決
Spring Boot Actuator 端點(diǎn)的未授權(quán)訪問(wèn)漏洞是一個(gè)安全性問(wèn)題,可能會(huì)導(dǎo)致未經(jīng)授權(quán)的用戶(hù)訪問(wèn)敏感的應(yīng)用程序信息,本文就來(lái)介紹一下解決方法,感興趣的可以了解一下2023-09-09