Java面試必考之如何在項(xiàng)目中優(yōu)雅的拋出異常
Java中的異常分類
Java中的異常機(jī)制是一種用于處理程序運(yùn)行時(shí)錯(cuò)誤和異常情況的機(jī)制。當(dāng)程序運(yùn)行時(shí)出現(xiàn)問題,如無法找到文件或網(wǎng)絡(luò)連接失敗等,就會(huì)拋出異常。這個(gè)過程稱為“拋出異常”。
在Java中,所有的異常都是派生自java.lang.Throwable類。Throwable類有兩個(gè)直接的子類:Exception和Error。Exception表示可處理的異常,而Error表示不可處理的異常。
首先詳細(xì)介紹下Error:
錯(cuò)誤(Error):是一些無法恢復(fù)或不可處理的錯(cuò)誤,通常是由 JVM 或底層操作系統(tǒng)引起的,比如 OutOfMemoryError、StackOverflowError 等。錯(cuò)誤無法被捕獲和處理,只能通過修改程序代碼或增加硬件資源等手段來避免。
而對于Exception異常類,有以下兩種類型:
受檢查異常/編譯時(shí)異常(Checked Exception):也稱為已檢查異常,這些異常在編譯時(shí)就必須進(jìn)行處理,否則會(huì)導(dǎo)致編譯錯(cuò)誤。通常是由外部不可控的因素引起的,比如輸入/輸出錯(cuò)誤、網(wǎng)絡(luò)異常、數(shù)據(jù)庫訪問異常等。受檢查異常包括 IOException、SQLException 等。
運(yùn)行時(shí)異常(Runtime Exception):也稱為未檢查異常,這些異常在編譯時(shí)不要求必須進(jìn)行處理,程序員可以選擇處理或不處理。通常是由程序中的邏輯錯(cuò)誤引起的,比如空指針引用、下標(biāo)越界、算術(shù)異常等。運(yùn)行時(shí)異常包括 NullPointerException、IndexOutOfBoundsException、ArithmeticException 等。
如何處理異常
上面講述了異常的分類,那么我們?nèi)绾翁幚懋惓D兀?/p>
這里先給出答案,我們可以通過一些關(guān)鍵字或者代碼塊處理異常,接下來將詳細(xì)介紹下幾種方式。
try…catch…finally
Java 異常機(jī)制基于三個(gè)關(guān)鍵字:try、catch 和 finally。我們開發(fā)者可以將可能拋出異常的代碼放在 try 語句塊中,在 catch 塊中捕獲并處理這些異常,也可以使用 finally 塊在任何情況下都執(zhí)行必要的清理工作。
其結(jié)構(gòu)如下所示:
try { // 可能拋出異常的代碼 } catch (ExceptionType1 e) { // 處理 ExceptionType1 類型異常 } catch (ExceptionType2 e) { // 處理 ExceptionType2 類型異常 } finally { // finally 塊中的代碼始終都會(huì)被執(zhí)行 }
在上面的代碼中,我們使用 try-catch 來捕獲可能拋出的受檢查異常和運(yùn)行時(shí)異常,對于必須關(guān)閉的資源,我們通常會(huì)在 finally 塊中進(jìn)行關(guān)閉。
無論 try 塊中是否發(fā)生異常,finally 塊中的代碼都會(huì)被執(zhí)行。finally 塊通常用于釋放資源、清理工作等操作,比如關(guān)閉文件句柄、釋放內(nèi)存等。即使在 try 或 catch 塊中有 return 語句,finally 塊也會(huì)在這些語句之后執(zhí)行。
需要注意的是,finally 塊不一定要和 catch 塊一起使用,也可以單獨(dú)出現(xiàn)。此外,在 Java 7 中,還引入了一個(gè)新的關(guān)鍵字 try-with-resources,用于自動(dòng)釋放資源的處理方式,可以進(jìn)一步簡化代碼。
try-with-resources
try-with-resources是Java 7引入的一種新的異常處理機(jī)制,主要用于處理需要關(guān)閉資源的情況。在這種機(jī)制下,我們可以通過try塊中聲明資源對象的方式,自動(dòng)管理這些資源對象的釋放和關(guān)閉。
使用try-with-resources機(jī)制的代碼結(jié)構(gòu)如下:
try (ResourceType resourceVar1 = ResourceInitialization1; ResourceType resourceVar2 = ResourceInitialization2; ...) { // Code that uses the resourceVar1 and/or resourceVar2. } catch (ExceptionType e) { // Exception handling code. }
在這里,ResourceType是需要關(guān)閉的資源類型,resourceVar是資源變量名,ResourceInitialization是一個(gè)表達(dá)式,用來初始化資源。多個(gè)資源之間用分號分隔。在try塊結(jié)束后,程序會(huì)自動(dòng)調(diào)用資源的close方法,從而釋放資源。
try-with-resources機(jī)制使得資源管理變得更加簡單、可讀性更強(qiáng),并且減少了忘記釋放資源的可能性。此外,此機(jī)制還支持對異常處理的自動(dòng)化控制,可以簡化代碼的結(jié)構(gòu)和調(diào)試過程。
當(dāng)然,這里也有我們需要注意的點(diǎn),只有實(shí)現(xiàn)了AutoCloseable接口的資源對象才能夠在try-with-resources機(jī)制下使用。如果資源對象未實(shí)現(xiàn)AutoCloseable接口,則需要使用上面介紹的傳統(tǒng)的try-catch-finally語句塊來手動(dòng)釋放資源。
throw關(guān)鍵字處理異常
在處理異常時(shí),throw關(guān)鍵字用于手動(dòng)拋出異常。使用 throw 語句時(shí),在代碼塊中會(huì)創(chuàng)建一個(gè)指定異常類的對象,該對象包含有關(guān)異常類型和異常信息的詳細(xì)信息,并將其傳遞給調(diào)用者。
throw 語法如下所示:
throw exceptionObject;
其中,exceptionObject 表示要拋出的異常對象。exceptionObject 必須是 throwable 類或其子類的一個(gè)實(shí)例。
通常情況下,在某些條件不滿足時(shí)需要拋出異常,而這種情況違反了當(dāng)前環(huán)境和程序邏輯的約束。由于異常的提出與處理可能更加容易,因此認(rèn)為拋出異常是一種更好的解決方案。
我們以一個(gè)簡單的示例,說明如何使用 throw 語句來顯式拋出一個(gè)異常:
public class Example { public static void main(String[] args) { try { int a=10, b=0; if(b==0) throw new ArithmeticException("除數(shù)為0"); else System.out.println(a/b); } catch (ArithmeticException e) { System.out.println(e.getMessage()); } } }
在這個(gè)例子中,當(dāng)被除數(shù)值等于零時(shí),它將執(zhí)行 throw 語句向次級方法拋出 ArithmeticException 異常。如果沒有拋出異常,將在 console 中打印結(jié)果。
最后需要注意的是,當(dāng)代碼遇到 throw 語句時(shí),它將立即停止當(dāng)前代碼塊的執(zhí)行,并將控制權(quán)傳遞到異常處理程序中。如果沒有定義錯(cuò)誤處理程序,則會(huì)引發(fā)運(yùn)行時(shí)錯(cuò)誤并終止程序的執(zhí)行。因此,在使用 throw 語句之前,需要確保適當(dāng)?shù)靥幚懋惓!?/p>
throws關(guān)鍵字處理異常
在使用throws關(guān)鍵字處理異常,throws關(guān)鍵字用于告訴編譯器一個(gè)方法可能會(huì)拋出哪些類型的異常。這個(gè)關(guān)鍵字通常用在方法的聲明中,并且可以跟一個(gè)或多個(gè)異常類名。
方法聲明示例:
public void readFile() throws IOException { // code that reads file. }
在上面的代碼中,readFile()方法可能會(huì)拋出IOException異常,因此使用了throws關(guān)鍵字來聲明。這意味著在調(diào)用該方法時(shí),調(diào)用者必須處理或重新拋出IOException異常。
當(dāng)有多個(gè)異??赡軙?huì)被拋出時(shí),可以使用逗號分隔它們:
public void connectToServer() throws IOException, InterruptedException { // code that connects to server. }
如果一個(gè)方法沒有通過throws關(guān)鍵字聲明可能會(huì)拋出的異常,而在方法內(nèi)部又拋出了異常,那么編譯器將會(huì)提示一個(gè)編譯錯(cuò)誤。
使用throws關(guān)鍵字,可以使得我們更好地組織自己的代碼,并且提高代碼的可讀性和可維護(hù)性。調(diào)用者可以根據(jù)方法聲明中列出的異常類型,進(jìn)行更加精準(zhǔn)的異常處理。同時(shí),使用throws關(guān)鍵字也要求方法實(shí)現(xiàn)者更加注意異常處理,并且編寫更加健壯的代碼。
throw關(guān)鍵字和throws關(guān)鍵字區(qū)別
上面我們介紹了throw和throws關(guān)鍵字來處理異常,相信火眼金睛的大佬可能已經(jīng)看出了兩者的區(qū)別,在這里再總結(jié)一下:
throw 關(guān)鍵字:
throw 是一個(gè)操作符,用于手動(dòng)拋出一個(gè)異常對象。
通常情況下,在某些條件不滿足時(shí)需要拋出異常,違反了當(dāng)前環(huán)境和程序邏輯的約束。使用 throw 能夠顯式地拋出一個(gè)異常,使錯(cuò)誤信息更加清晰明確。
throws 關(guān)鍵字:
throws 關(guān)鍵字用于方法簽名中,用于聲明給調(diào)用者該方法可能會(huì)拋出的異常類型方便捕獲處理或者繼續(xù)向外拋出(由上層處理)。
如果一個(gè)方法可能會(huì)拋出異常,就可以使用 throws 在方法聲明中指定該異常。這樣做是為了讓調(diào)用該方法的代碼知道處理這個(gè)異常,或者依次傳遞給其上層方法來處理。
throws 可以聲明多個(gè)異常,例如: public void testMethod() throws Exception1, Exception2 {...}
上述兩個(gè)關(guān)鍵字的區(qū)別在于,throw 是用于手動(dòng)拋出異常,而 throws 是在方法簽名中聲明該方法有可能會(huì)拋出的異常并把異常交給其他方法進(jìn)行處理。
使用 throw 拋出異常時(shí),要么在方法內(nèi)部 try…catch 捕獲并處理,要么通過 throws 在方法簽名中聲明可能拋出的異常類型。
到此這篇關(guān)于Java面試必考之如何在項(xiàng)目中優(yōu)雅的拋出異常的文章就介紹到這了,更多相關(guān)Java拋出異常內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過圖例了解IDEA引入JQuery實(shí)現(xiàn)步驟
這篇文章主要介紹了IDEA引入JQuery實(shí)現(xiàn)步驟圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09SpringBoot項(xiàng)目使用MDC給日志增加唯一標(biāo)識(shí)的實(shí)現(xiàn)步驟
本文介紹了如何在SpringBoot項(xiàng)目中使用MDC(Mapped?Diagnostic?Context)為日志增加唯一標(biāo)識(shí),以便于日志追蹤,通過創(chuàng)建日志攔截器、配置攔截器以及修改日志配置文件,可以實(shí)現(xiàn)這一功能,文章還提供了源碼地址,方便讀者學(xué)習(xí)和參考,感興趣的朋友一起看看吧2025-03-03MyBatisPlus分頁的同時(shí)指定排序規(guī)則說明
這篇文章主要介紹了MyBatisPlus分頁的同時(shí)指定排序規(guī)則說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12mybatis-plus指定字段模糊查詢的實(shí)現(xiàn)方法
最近項(xiàng)目中使用springboot+mybatis-plus來實(shí)現(xiàn),所以下面這篇文章主要給大家介紹了關(guān)于mybatis-plus實(shí)現(xiàn)指定字段模糊查詢的相關(guān)資料,需要的朋友可以參考下2022-04-04springboot + mybatis + druid + 多數(shù)據(jù)源的問題詳解
這篇文章主要介紹了springboot + mybatis + druid + 多數(shù)據(jù)源的問題詳解,示例代碼文字相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09