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

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

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

1. 前言

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

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

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

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


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

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

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

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

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

标签:
  • 热门焦点
  • 7月安卓手机好评榜:三星S23Ultra好评率第一

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年7月1日至7月31日,仅限国内市场。第一名:三星Galaxy S23 Ultra好评率:95.71%在即将迎来新
  • JavaScript学习 -AES加密算法

    引言在当今数字化时代,前端应用程序扮演着重要角色,用户的敏感数据经常在前端进行加密和解密操作。然而,这样的操作在网络传输和存储中可能会受到恶意攻击的威胁。为了确保数据
  • “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • 小米汽车电池信息疑似曝光:容量101kWh,支持800V高压快充

    7月14日消息,今日一名博主在社交媒体发布了一张疑似小米汽车电池信息的照片,显示该电池包正是宁德时代麒麟电池,容量为101kWh,电压为726.7V,可以预测小
  • 8月见!小米MIX Fold 3获得3C认证:支持67W快充

    这段时间以来,包括三星、一加、荣耀等等有不少品牌旗下的最新折叠屏旗舰都得到了不少爆料,而小米新一代折叠屏旗舰——小米MIX Fold 3此前也屡屡被传
  • 2纳米决战2025

    集微网报道 从三强争霸到四雄逐鹿,2nm的厮杀声已然隐约传来。无论是老牌劲旅台积电、三星,还是誓言重回先进制程领先地位的英特尔,甚至初成立不久的新
  • Windows 11发布,微软一改往常对老机型开放的态度

    距离 Windows 11 发布已经过去一周,在过去一周里,很多数码爱好者围绕其对 Android 应用的支持、对老机型的升级问题展开了激烈讨论。与以往不同的是,在这次大
  • 由于成本持续增加,笔记本产品价格预计将明显上涨

    根据知情人士透露,由于材料、物流等成本持续增加,笔记本产品价格预计将在2021年下半年有明显上涨。进入6月下旬以来,全球半导体芯片缺货情况加剧,显卡、处理器
  • Meta盲目扩张致超万人被裁,重金押注元宇宙而前景未明

    图片来源:图虫创意日前,Meta创始人兼CEO 马克&middot;扎克伯发布公开信,宣布Meta计划裁员超11000人,占其员工总数13%。他公开承认了自己的预判失误:&ldquo;不仅
Top