日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

一篇文章徹底理解 Java 的 Suppressed exceptions 機(jī)制

來(lái)源: 責(zé)編: 時(shí)間:2024-05-17 17:47:19 183觀看
導(dǎo)讀1. 前言在查看 JAVA 應(yīng)用拋出的異常堆棧以排查問(wèn)題時(shí),我們有時(shí)會(huì)看到所謂 suppressed exceptions,即被抑制的異常。理解 suppressed exceptions 的原理,對(duì)我們分析問(wèn)題的底層真實(shí)原因大有裨益。所以本文分析總結(jié)下 Java

1. 前言

在查看 JAVA 應(yīng)用拋出的異常堆棧以排查問(wèn)題時(shí),我們有時(shí)會(huì)看到所謂 suppressed exceptions,即被抑制的異常。理解 suppressed exceptions 的原理,對(duì)我們分析問(wèn)題的底層真實(shí)原因大有裨益。所以本文分析總結(jié)下 Java 中的 suppressed exceptions。1mz28資訊網(wǎng)——每日最新資訊28at.com

2. suppressed exceptions 機(jī)制總結(jié)

  • 簡(jiǎn)單來(lái)說(shuō),suppressed exceptions 是 JVM 中一個(gè)真實(shí)發(fā)生了的異常,但由于某些原因被 JVM 忽略/抑制了;
  • 一個(gè)常見(jiàn)的異常被忽略/抑制的場(chǎng)景是 try-catch-finally 代碼塊:由于無(wú)論 try 代碼塊是否正常執(zhí)行結(jié)束,finally 代碼塊都會(huì)執(zhí)行,所以如果 try 代碼塊和 finally 代碼塊都拋出異常時(shí),為在打印的異常堆棧中完整還原異常現(xiàn)場(chǎng),代碼中可以做特殊處理(具體的處理方式見(jiàn)后文),以將兩個(gè)異常都打印,并標(biāo)記 try 中的異常為 suppressed;(用戶需要對(duì)異常代碼做處理);
  • 另一個(gè)常見(jiàn)的異常被忽略的場(chǎng)景是 try-with-resources 代碼塊:java7 引進(jìn)了 try-with-resources 代碼塊和 AutoCloseable 接口來(lái)管理資源,當(dāng) try-with-resources 底層的業(yè)務(wù)邏輯代碼執(zhí)行完畢時(shí),無(wú)論其執(zhí)行是否正常結(jié)束,jvm 都會(huì)自動(dòng)關(guān)閉 try 中指定的 AutoCloseable 資源,以避免資源泄露,如果業(yè)務(wù)邏輯代碼的處理和 AutoCloseable 資源的關(guān)閉都發(fā)生了異常,此時(shí) jvm 會(huì)將兩個(gè)異常都打印,并標(biāo)記關(guān)閉 AutoCloseable 資源觸發(fā)的異常為try 中的異常為 suppressed;(用戶不用做特殊處理);
  • 所以,為有效利用 suppressed exceptions 機(jī)制妥善打印異常堆棧以輔助問(wèn)題排查,從 Java 7 開始, 我們可以使用 Throwable 類的如下方法來(lái)處理 suppressed exceptions: 即 java.lang.Throwable#addSuppressed 和java.lang.Throwable#getSuppressed
  • A suppressed exception is an exception that is thrown but somehow ignored;
  • A common scenario for this is the try-catch-finally block: when the finally block throws an exception,any exception originally thrown in the try block is then suppressed;
  • Another common scenario is the try-with-resources block:Java 7 introduced the try-with-resources construct and the AutoCloseable interface for resource management,when exception occurs both in the business processing and resource closing,it’s the exception thrown in the close method that’s suppressed;
  • Starting with Java 7, we can now use two methods on the Throwable class to handle our suppressed exceptions: addSuppressed and getSuppressed.

3 suppressed exceptions 機(jī)制 細(xì)節(jié)- try-catch-finally 代碼塊

  • 當(dāng) finally 代碼塊沒(méi)有使用 java.lang.Throwable#addSuppressed 對(duì)異常進(jìn)行特殊處理時(shí),如果 try 代碼塊和 finally 代碼塊都拋出異常,打印的異常堆棧的示例如下,可以看到,沒(méi)有打印try 中的異常,而僅僅打印了 finally 中的異常,此時(shí)用戶顯然無(wú)法輕易獲知異常的真實(shí)原因;
java.lang.NullPointerExceptionat com.keep.bdata.SuppressedExceptionsDemo.demoExceptionWithNoSuppress(SuppressedExceptionsDemo.java:21)at com.keep.bdata.SuppressedExceptionsDemo.givenNonExistentFileName_whenAttemptFileOpen_thenNullPointerException(SuppressedExceptionsDemo.java:12)

圖片圖片1mz28資訊網(wǎng)——每日最新資訊28at.com

  • 當(dāng) finally 代碼塊使用 java.lang.Throwable#addSuppressed 對(duì)異常進(jìn)行了特殊處理時(shí),如果 try 代碼塊和 finally 代碼塊都拋出異常,打印的異常堆棧的示例如下,可以看到,try 中的異常和 finally 中的異常都被打印了,且 try 中的異常被標(biāo)記為 suppressed exceptions, 如果用戶理解 suppressed exceptions 的機(jī)制,通過(guò)這些異常堆棧,顯然可以輕松獲知異常的真實(shí)原因;
java.lang.NullPointerException	at com.keep.bdata.SuppressedExceptionsDemo.demoExceptionWithSuppressed(SuppressedExceptionsDemo.java:38)	at com.keep.bdata.SuppressedExceptionsDemo.givenNonExistentFileName_whenAttemptFileOpen_thenNullPointerException_withSuppressed(SuppressedExceptionsDemo.java:27)	Suppressed: java.io.FileNotFoundException: /non-existent-path/non-existent-file.txt (系統(tǒng)找不到指定的路徑。)		at java.io.FileInputStream.open0(Native Method)		at java.io.FileInputStream.open(FileInputStream.java:195)		at java.io.FileInputStream.<init>(FileInputStream.java:138)		at java.io.FileInputStream.<init>(FileInputStream.java:93)		at com.keep.bdata.SuppressedExceptionsDemo.demoExceptionWithSuppressed(SuppressedExceptionsDemo.java:33)

圖片圖片1mz28資訊網(wǎng)——每日最新資訊28at.com

4 suppressed exceptions 機(jī)制 細(xì)節(jié) - try-with-resources 代碼塊

  • java7 引進(jìn)了 try-with-resources 代碼塊和 AutoCloseable 接口來(lái)管理資源,當(dāng) try-with-resources 底層的業(yè)務(wù)邏輯代碼執(zhí)行完畢時(shí),無(wú)論其執(zhí)行是否正常結(jié)束,jvm 都會(huì)自動(dòng)關(guān)閉 try 中指定的 AutoCloseable 資源,以避免資源泄露;
  • 如果業(yè)務(wù)邏輯代碼的處理和 AutoCloseable 資源的關(guān)閉都發(fā)生了異常,此時(shí) jvm 會(huì)將兩個(gè)異常都打印,并標(biāo)記關(guān)閉 AutoCloseable 資源觸發(fā)的異常為try 中的異常為 suppressed,打印的異常堆棧的示例如下,如果用戶理解 suppressed exceptions 的機(jī)制,通過(guò)這些異常堆棧,顯然可以輕松獲知異常的真實(shí)原因;
  • 注意這是jvm自己實(shí)現(xiàn)的,用戶不需要對(duì)代碼做特殊處理;
java.lang.IllegalArgumentException: Thrown from processSomething()	at com.keep.bdata.TryWithResourceDemo$ExceptionalResource.processSomething(TryWithResourceDemo.java:23)	at com.keep.bdata.TryWithResourceDemo.demoExceptionalResource(TryWithResourceDemo.java:17)	at com.keep.bdata.TryWithResourceDemo.givenNonExistentFileName_whenAttemptFileOpen_thenNullPointerException_suppressed(TryWithResourceDemo.java:12)	Suppressed: java.lang.NullPointerException: Thrown from close()		at com.keep.bdata.TryWithResourceDemo$ExceptionalResource.close(TryWithResourceDemo.java:28)		at com.keep.bdata.TryWithResourceDemo.demoExceptionalResource(TryWithResourceDemo.java:18)

圖片圖片1mz28資訊網(wǎng)——每日最新資訊28at.com

5 suppressed exceptions 機(jī)制完整示例代碼

  • suppressed exceptions 機(jī)制的完整示例代碼如下(try-catch-finally ):
package com.keep.bdata;import org.junit.jupiter.api.Test;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;publicclass SuppressedExceptionsDemo {    @Test    public void givenNonExistentFileName_whenAttemptFileOpen_thenNullPointerException() throws IOException {        demoExceptionWithNoSuppress("/non-existent-path/non-existent-file.txt");    }    public static void demoExceptionWithNoSuppress(String filePath) throws IOException {        FileInputStream fileIn = null;        try {            fileIn = new FileInputStream(filePath);        } catch (FileNotFoundException e) {            thrownew IOException(e);        } finally {            fileIn.close();        }    }    @Test    public void givenNonExistentFileName_whenAttemptFileOpen_thenNullPointerException_withSuppressed() throws IOException{        demoExceptionWithSuppressed("/non-existent-path/non-existent-file.txt");    }    public static void demoExceptionWithSuppressed(String filePath) throws IOException {        Throwable firstException = null;        FileInputStream fileIn = null;        try {            fileIn = new FileInputStream(filePath);        } catch (IOException e) {            firstException = e;        } finally {            try {                fileIn.close();            } catch (NullPointerException npe) {                if (firstException != null) {                    npe.addSuppressed(firstException);                }                throw npe;            }        }    }}
  • suppressed exceptions 機(jī)制的完整示例代碼如下(try-with-resources 完整示例代碼):
package com.keep.bdata;import org.junit.jupiter.api.Test;publicclass TryWithResourceDemo  {    @Test    public void givenNonExistentFileName_whenAttemptFileOpen_thenNullPointerException_suppressed() throws Exception {        demoExceptionalResource();    }    public void demoExceptionalResource() throws Exception {        try (ExceptionalResource exceptionalResource = new ExceptionalResource()) {            exceptionalResource.processSomething();        }    }    class ExceptionalResource implements AutoCloseable {        public void processSomething() {            thrownew IllegalArgumentException("Thrown from processSomething()");        }        @Override        public void close() throws Exception {            thrownew NullPointerException("Thrown from close()");        }    }


1mz28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-88927-0.html一篇文章徹底理解 Java 的 Suppressed exceptions 機(jī)制

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 一文徹底搞明白享元模式

下一篇: 在.Net開發(fā)中使用Math.NET Filtering開源庫(kù)實(shí)現(xiàn)巴特沃斯濾波器

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 桐柏县| 特克斯县| 恩平市| 江口县| 宁南县| 彰武县| 宁安市| 高尔夫| 广西| 鄂伦春自治旗| 开封县| 北安市| 西和县| 高密市| 西乌珠穆沁旗| 中阳县| 高雄县| 淮北市| 米脂县| 广汉市| 北京市| 贡山| 白城市| 武冈市| 县级市| 图们市| 兴和县| 蚌埠市| 鸡东县| 富顺县| 眉山市| 宁河县| 库尔勒市| 托克托县| 富川| 马关县| 利川市| 海宁市| 容城县| 田东县| 闵行区|