AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

一篇文章徹底理解 Java 的 Suppressed exceptions 機制

來源: 責編: 時間:2024-05-17 17:47:19 149觀看
導讀1. 前言在查看 JAVA 應用拋出的異常堆棧以排查問題時,我們有時會看到所謂 suppressed exceptions,即被抑制的異常。理解 suppressed exceptions 的原理,對我們分析問題的底層真實原因大有裨益。所以本文分析總結下 Java

1. 前言

在查看 JAVA 應用拋出的異常堆棧以排查問題時,我們有時會看到所謂 suppressed exceptions,即被抑制的異常。理解 suppressed exceptions 的原理,對我們分析問題的底層真實原因大有裨益。所以本文分析總結下 Java 中的 suppressed exceptions。16d28資訊網——每日最新資訊28at.com

2. suppressed exceptions 機制總結

  • 簡單來說,suppressed exceptions 是 JVM 中一個真實發生了的異常,但由于某些原因被 JVM 忽略/抑制了;
  • 一個常見的異常被忽略/抑制的場景是 try-catch-finally 代碼塊:由于無論 try 代碼塊是否正常執行結束,finally 代碼塊都會執行,所以如果 try 代碼塊和 finally 代碼塊都拋出異常時,為在打印的異常堆棧中完整還原異常現場,代碼中可以做特殊處理(具體的處理方式見后文),以將兩個異常都打印,并標記 try 中的異常為 suppressed;(用戶需要對異常代碼做處理);
  • 另一個常見的異常被忽略的場景是 try-with-resources 代碼塊:java7 引進了 try-with-resources 代碼塊和 AutoCloseable 接口來管理資源,當 try-with-resources 底層的業務邏輯代碼執行完畢時,無論其執行是否正常結束,jvm 都會自動關閉 try 中指定的 AutoCloseable 資源,以避免資源泄露,如果業務邏輯代碼的處理和 AutoCloseable 資源的關閉都發生了異常,此時 jvm 會將兩個異常都打印,并標記關閉 AutoCloseable 資源觸發的異常為try 中的異常為 suppressed;(用戶不用做特殊處理);
  • 所以,為有效利用 suppressed exceptions 機制妥善打印異常堆棧以輔助問題排查,從 Java 7 開始, 我們可以使用 Throwable 類的如下方法來處理 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 機制 細節- try-catch-finally 代碼塊

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

圖片圖片16d28資訊網——每日最新資訊28at.com

  • 當 finally 代碼塊使用 java.lang.Throwable#addSuppressed 對異常進行了特殊處理時,如果 try 代碼塊和 finally 代碼塊都拋出異常,打印的異常堆棧的示例如下,可以看到,try 中的異常和 finally 中的異常都被打印了,且 try 中的異常被標記為 suppressed exceptions, 如果用戶理解 suppressed exceptions 的機制,通過這些異常堆棧,顯然可以輕松獲知異常的真實原因;
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 (系統找不到指定的路徑。)		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)

圖片圖片16d28資訊網——每日最新資訊28at.com

4 suppressed exceptions 機制 細節 - try-with-resources 代碼塊

  • java7 引進了 try-with-resources 代碼塊和 AutoCloseable 接口來管理資源,當 try-with-resources 底層的業務邏輯代碼執行完畢時,無論其執行是否正常結束,jvm 都會自動關閉 try 中指定的 AutoCloseable 資源,以避免資源泄露;
  • 如果業務邏輯代碼的處理和 AutoCloseable 資源的關閉都發生了異常,此時 jvm 會將兩個異常都打印,并標記關閉 AutoCloseable 資源觸發的異常為try 中的異常為 suppressed,打印的異常堆棧的示例如下,如果用戶理解 suppressed exceptions 的機制,通過這些異常堆棧,顯然可以輕松獲知異常的真實原因;
  • 注意這是jvm自己實現的,用戶不需要對代碼做特殊處理;
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)

圖片圖片16d28資訊網——每日最新資訊28at.com

5 suppressed exceptions 機制完整示例代碼

  • suppressed exceptions 機制的完整示例代碼如下(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 機制的完整示例代碼如下(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()");        }    }


16d28資訊網——每日最新資訊28at.com

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

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

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

下一篇: 在.Net開發中使用Math.NET Filtering開源庫實現巴特沃斯濾波器

標簽:
  • 熱門焦點
Top