成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發 前端
在查看 JAVA 應用拋出的異常堆棧以排查問題時,我們有時會看到所謂 suppressed exceptions,即被抑制的異常。理解 suppressed exceptions 的原理,對我們分析問題的底層真實原因大有裨益。所以本文分析總結下 Java 中的 suppressed exceptions。

1. 前言

在查看 JAVA 應用拋出的異常堆棧以排查問題時,我們有時會看到所謂 suppressed exceptions,即被抑制的異常。理解 suppressed exceptions 的原理,對我們分析問題的底層真實原因大有裨益。所以本文分析總結下 Java 中的 suppressed exceptions。

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.NullPointerException
at com.keep.bdata.SuppressedExceptionsDemo.demoExceptionWithNoSuppress(SuppressedExceptionsDemo.java:21)
at com.keep.bdata.SuppressedExceptionsDemo.givenNonExistentFileName_whenAttemptFileOpen_thenNullPointerException(SuppressedExceptionsDemo.java:12)

圖片圖片

  • 當 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)

圖片圖片

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)

圖片圖片

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()");
        }
    }


責任編輯:武曉燕 來源: 明哥的IT隨筆
相關推薦

2017-07-20 16:55:56

Android事件響應View源碼分析

2024-06-25 08:18:55

2021-04-07 13:28:21

函數程序員異步

2013-04-15 10:59:08

iOS開發ARC版本說明

2025-01-26 15:38:11

Spring事務編程式

2022-01-05 10:22:17

HiveAuthenticat認證

2020-10-09 08:15:11

JsBridge

2015-07-15 17:09:48

HiveHadoop分布式文件系統

2019-07-23 08:55:46

Base64編碼底層

2023-05-08 08:21:15

JavaNIO編程

2021-07-01 10:01:16

JavaLinkedList集合

2024-05-10 08:19:59

arthasjava字節碼

2024-01-30 09:31:53

SQL語言數據庫

2020-12-29 05:35:43

FlinkSQL排序

2025-03-07 10:04:12

2022-02-21 09:44:45

Git開源分布式

2023-05-12 08:19:12

Netty程序框架

2019-04-17 15:16:00

Sparkshuffle算法

2021-04-09 08:40:51

網絡保險網絡安全網絡風險

2021-06-30 00:20:12

Hangfire.NET平臺
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩视频在线免费观看 | 国产精品久久久久久久久图文区 | 三级成人片 | 中文字幕国产视频 | 国内自拍视频在线观看 | 精品福利在线 | 亚洲a视频 | 久久久久久国产精品 | 亚洲成人免费 | 亚洲天堂一区 | 黄网站色大毛片 | 亚洲精品www | 黄色在线免费观看视频网站 | 啪啪综合网| 久久久蜜桃 | 国产电影一区二区三区爱妃记 | 亚洲综合国产精品 | 人人做人人澡人人爽欧美 | 国产精品极品美女在线观看免费 | 蜜臀91视频 | 国产成人免费视频网站高清观看视频 | 九九九久久国产免费 | 一级a爱片久久毛片 | 亚洲一区视频在线 | 欧美精品一区二区三区四区 在线 | 波多野结衣先锋影音 | 国产91精品久久久久久久网曝门 | 国产一区二区麻豆 | 国产三级日本三级 | 一区二区三区视频在线观看 | 五月天天丁香婷婷在线中 | 性生活毛片| 美女黄18岁以下禁止观看 | 在线看av网址 | 国产丝袜一区二区三区免费视频 | 成人久久久久 | 欧美日韩高清免费 | 国产男女精品 | 91原创视频 | 亚洲国产高清高潮精品美女 | 女人精96xxx免费网站p |