当前位置:首页 > 科技  > 软件

一篇文章彻底理解 Java 的 Suppressed exceptions 机制

来源: 责编: 时间:2024-05-17 17:47:19 279观看
导读1. 前言在查看 JAVA 应用抛出的异常堆栈以排查问题时,我们有时会看到所谓 suppressed exceptions,即被抑制的异常。理解 suppressed exceptions 的原理,对我们分析问题的底层真实原因大有裨益。所以本文分析总结下 Java

1. 前言

在查看 JAVA 应用抛出的异常堆栈以排查问题时,我们有时会看到所谓 suppressed exceptions,即被抑制的异常。理解 suppressed exceptions 的原理,对我们分析问题的底层真实原因大有裨益。所以本文分析总结下 Java 中的 suppressed exceptions。xB228资讯网——每日最新资讯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)

图片图片xB228资讯网——每日最新资讯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)

图片图片xB228资讯网——每日最新资讯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)

图片图片xB228资讯网——每日最新资讯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()");        }    }


xB228资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-88927-0.html一篇文章彻底理解 Java 的 Suppressed exceptions 机制

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

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

下一篇: 在.Net开发中使用Math.NET Filtering开源库实现巴特沃斯滤波器

标签:
  • 热门焦点
  • K60至尊版刚预热 一加Ace2 Pro正面硬刚

    Redmi这边刚如火如荼的宣传了K60 Ultra的各种技术和硬件配置,作为竞品的一加也坐不住了。一加中国区总裁李杰发布了两条微博,表示在自家的一加Ace2上早就已经采用了和PixelWo
  • vivo TWS Air开箱体验:真轻 臻好听

    在vivo S15系列新机的发布会上,vivo的最新款真无线蓝牙耳机vivo TWS Air也一同发布,本次就这款耳机新品给大家带来一个简单的分享。外包装盒上,vivo TWS Air保持了vivo自家产
  • 28个SpringBoot项目中常用注解,日常开发、求职面试不再懵圈

    前言在使用SpringBoot开发中或者在求职面试中都会使用到很多注解或者问到注解相关的知识。本文主要对一些常用的注解进行了总结,同时也会举出具体例子,供大家学习和参考。注解
  • 线程通讯的三种方法!通俗易懂

    线程通信是指多个线程之间通过某种机制进行协调和交互,例如,线程等待和通知机制就是线程通讯的主要手段之一。 在 Java 中,线程等待和通知的实现手段有以下几种方式:Object 类下
  • 网红炒股不为了赚钱,那就是耍流氓!

    来源:首席商业评论6月26日高调宣布入市,网络名嘴大v胡锡进居然进军了股市。在一次财经媒体峰会上,几个财经圈媒体大佬就&ldquo;胡锡进炒股是否知道认真报道&rdquo;展开讨论。有
  • 到手价3099元起!iQOO Neo8 Pro今日首销:安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
  • Android 14发布:首批适配机型公布

    5月11日消息,谷歌在今天凌晨举行了I/O大会,本次发布会谷歌带来了自家的AI语言模型PaLM 2、谷歌Pixel Fold折叠屏、谷歌Pixel 7a手机,同时发布了Androi
  • SN570 NVMe SSD固态硬盘 价格与性能兼具

    SN570 NVMe SSD固态硬盘是西部数据发布的最新一代WD Blue系列的固态硬盘,不仅闪存技术更为精进,性能也得到了进一步的跃升。WD Blue SN570 NVMe SSD的包装外
  • 三翼鸟智能家居亮相电博会,让用户体验更真实

    2021电博会在青岛国际会展中心开幕中,三翼鸟直接把“家”搬到了现场,成为了展会的一大看点。这也是三翼鸟继9月9日发布了行业首个一站式定制智慧家平台后的
Top