Java常見踩坑記錄之異常處理
一、Java異常類層次結(jié)構(gòu)

Java中,所有的異常都來源于java.lang包中的Throwable類,它有兩個重要的子類,Exception(異常)和Error(錯誤)。
- Exception :程序本身可以處理的異常,可以通過 catch 來進行捕獲。Exception 又可以分為 受檢查異常(必須處理) 和 不受檢查異常(可以不處理)。
- Error :Error 屬于程序無法處理的錯誤 ,我們沒辦法通過 catch 來進行捕獲 。例如,虛擬機內(nèi)存不夠錯誤(OutOfMemoryError)、類定義錯誤(NoClassDefFoundError)等 。這些異常發(fā)生時,Java 虛擬機(JVM)一般會線程終止。
二、Throwable類常用方法
- public String getMessage(): 返回異常發(fā)生時的簡要描述
- public String toString(): 返回異常發(fā)生時的詳細信息
- public String getLocalizedMessage():返回異常對象的本地化信息。使用 Throwable 的子類覆蓋這個方法,可以生成本地化信息。如果子類沒有覆蓋該方法,則該方法返回的信息與 getMessage()返回的結(jié)果相同
- public void printStackTrace():在控制臺上打印 Throwable 對象封裝的異常信息
三、try-catch-finally
- try塊: 用于捕獲異常。其后可接零個或多個 catch 塊,如果沒有 catch 塊,則必須跟一個 finally 塊。
- catch塊: 用于處理 try 捕獲到的異常。
- finally 塊: 無論是否捕獲或處理異常,finally 塊里的語句都會被執(zhí)行。當在 try 塊或 catch 塊中遇到 return 語句時,finally 語句塊將在方法返回之前被執(zhí)行。
在以下 2種特殊情況下,finally 塊不會被執(zhí)行:
- 在 try 或 finally塊中用了 System.exit(int)退出程序。但是,如果 System.exit(int) 在異常語句之后,finally 還是會被執(zhí)行
- 程序所在的線程死亡。
代碼示例:
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("test.txt"));
br.readLine();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
四、使用 try-with-resources 來代替try-catch-finally
1. 適用范圍(資源的定義): 任何實現(xiàn) java.lang.AutoCloseable 的對象
2. 關(guān)閉資源和 finally 塊的執(zhí)行順序: 在 try-with-resources 語句中,任何 catch 或 finally 塊在聲明的資源關(guān)閉后運行
《Effecitve Java》中明確指出:
面對必須要關(guān)閉的資源,我們總是應(yīng)該優(yōu)先使用 try-with-resources 而不是try-finally。隨之產(chǎn)生的代碼更簡短,更清晰,產(chǎn)生的異常對我們也更有用。try-with-resources語句讓我們更容易編寫必須要關(guān)閉的資源的代碼,若采用try-finally則幾乎做不到這點。
將上面的代碼例子改造:
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
代碼變得非常簡潔。
注意:try-with-resource中聲明的變量會隱式的加上final 關(guān)鍵字,所以無法再進行賦值。
五、自定義異常
在Java中要想創(chuàng)建自定義異常,需要繼承Throwable或者他的子類Exception。
因為父類已經(jīng)把異常信息的操作都完成了,所在子類只要在構(gòu)造時,將異常信息傳遞給父類通過super 語句即可。
代碼示例:
public class CustomException extends Exception {
//無參構(gòu)造方法
public CustomException(){
super();
}
//有參的構(gòu)造方法
public CustomException(String message){
super(message);
}
// 用指定的詳細信息和原因構(gòu)造一個新的異常
public CustomException(String message, Throwable cause){
super(message,cause);
}
//用指定原因構(gòu)造一個新的異常
public CustomException(Throwable cause) {
super(cause);
}
}
按照國際慣例,自定義的異常應(yīng)該總是包含如下的構(gòu)造函數(shù):
- 一個無參構(gòu)造函數(shù)
- 一個帶有String參數(shù)的構(gòu)造函數(shù),并傳遞給父類的構(gòu)造函數(shù)。
- 一個帶有String參數(shù)和Throwable參數(shù),并都傳遞給父類構(gòu)造函數(shù)
- 一個帶有Throwable 參數(shù)的構(gòu)造函數(shù),并傳遞給父類的構(gòu)造函數(shù)。
finally塊和return
首先一個不容易理解的事實:在 try塊中即便有return,break,continue等改變執(zhí)行流的語句,finally也會執(zhí)行。
finally中的return 會覆蓋 try 或者catch中的返回值。
finally中的return或異常會抑制(消滅)前面try或者catch塊中的異常。
總結(jié)
到此這篇關(guān)于Java常見踩坑記錄之異常處理的文章就介紹到這了,更多相關(guān)Java常見異常處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java攔截過濾器模式 (Intercepting Filter )實現(xiàn)方法
攔截過濾器模式(Intercepting Filter Pattern)用于對應(yīng)用程序的請求或響應(yīng)做一些預(yù)處理/后處理,本文通過實例代碼介紹Java攔截過濾器模式 (Intercepting Filter )的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧2024-03-03
Java描述數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之鏈表的增刪改查詳解
這篇文章主要給大家介紹了關(guān)于Java描述數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之鏈表的增刪改查的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05
Kafka是什么及如何使用SpringBoot對接Kafka(最新推薦)
這篇文章主要介紹了Kafka是什么,以及如何使用SpringBoot對接Kafka,今天我們通過一個Demo講解了在SpringBoot中如何對接Kafka,也介紹了下關(guān)鍵類?KafkaTemplate,需要的朋友可以參考下2023-11-11

