Java 7对抑制异常的支持

在JDK 7中 ,向Throwable类( Exception和Error类的父类)添加了一个新的构造函数和两个新方法。 添加了新的构造函数和两个新方法以支持“抑制的异常”(不要与吞咽或忽略异常的不良做法相混淆)。 在本文中,我将探讨为什么引入这些方法以及它们在JDK 7中的使用方式。我简短讨论了抑制异常与链式异常的不同之处。

被抑制的异常在新的Java 7 try-with-resources语句 (也称为自动资源管理 [ ARM ])的执行中起着重要作用。 为这种新的资源管理功能提供API支持似乎是Throwable类上新的构造函数和方法的主要驱动程序,它们提供对抑制的异常的访问,但是API支持在try-with-resources语句之外使用抑制的异常。 。

遇到受抑制的异常的最常见用例是,当try-with-resources语句(这是一种尝试类型,根据Java语言规范Java SE 7 Edition 14.20 ,它不需要catch或finally子句时)遇到一个异常。 try块中的异常,然后在隐式尝试关闭相关资源时遇到另一个异常。

为了说明这种情况,我组成了自己的“资源”,可以在try-with-resource语句中使用它,因为它实现了java.lang.AutoCloseable接口。 当使用它的代码尝试使用它时,此“顽皮资源”会故意引发异常,然后在调用重写的close方法(由AutoCloseable接口指定的唯一方法)时引发另一个异常,从而继续其不良形式。 接下来显示NaughtyResource的代码清单。

NaughtyResource.java

package dustin.examples;/*** Resource that throws exceptions both in its use and its closure and is only* intended for use in demonstrating Java 7's suppressed exceptions APIs. This* is not a well-behaved class.* * @author Dustin*/
public class NaughtyResource implements AutoCloseable
{/*** Method that intentionally throws an exception.* * @throws RuntimeException Thrown no matter how you call me.*/public void doNothingGood(){throw new RuntimeException("Nothing good can come of this.");}/*** The overridden closure method from AutoCloseable interface.* * @throws Exception Exception that might be thrown during closure of this*    resource.*/@Overridepublic void close() throws Exception{throw new UnsupportedOperationException("Not supported yet.");}
}

现在有了顽皮的资源,是时候使用顽皮的资源并演示抑制异常API。 下一张图片描述了如果尝试使用此资源而不捕获close方法隐式抛出的Exception且未声明该方法抛出该异常的情况,将发生什么情况。

这是javac提供的错误消息,如以下屏幕快照所示。

我已经显示了前两个屏幕快照,以强调对资源执行的隐式关闭调用。 NetBeans编辑器和控制台中显示的错误消息清楚地表明了这种情况。

下一个代码清单包含编译的SuppressedExceptions类的第一个版本。

SuppressedExceptions.java(版本1)

package dustin.examples;/*** Demonstrate JDK 7's Suppressed Exceptions API support.* * @author Dustin*/
public class SuppressedExceptions
{/*** Executable function demonstrating suppressed exceptions.* * @param arguments The command line arguments; none expected.*/public static void main(String[] arguments) throws Exception{try (NaughtyResource naughty = new NaughtyResource()){naughty.doNothingGood();}}
}

尽管在执行上述代码时确实遇到了两个异常(一个在NaughtyResource.doNothingGood()调用的try块中,一个在隐式调用close方法的调用中),但只有一个渗透到顶部,并在应用程序显示时显示运行。 下一个屏幕快照对此进行了演示。

如最后一个图像所示,仅显示在try-with-resources语句的try try块中遇到的异常。 在这里,可以向Throwable(在这种情况下为Exception)询问其受抑制的异常的功能非常有用。 为了证明这一点,接下来显示SuppressedExceptions类的版本2(使用Throwable.getSuppressed() )。

SuppressedExceptions.java(版本2)

package dustin.examples;import static java.lang.System.err;/*** Demonstrate JDK 7's Suppressed Exceptions API support.* * @author Dustin*/
public class SuppressedExceptions
{/*** Method that uses NaughtyResource with try-with-resource statement.* * @throws Exception Expected exception for try-with-resource used on the*    NaughtyResource.*/public static void performTryWithResource() throws Exception{try (NaughtyResource naughty = new NaughtyResource()){naughty.doNothingGood();}  }/*** Executable function demonstrating suppressed exceptions.* * @param arguments The command line arguments; none expected.*/public static void main(String[] arguments){try{performTryWithResource();}catch (Exception ex){err.println("Exception encountered: " + ex.toString());final Throwable[] suppressedExceptions = ex.getSuppressed();final int numSuppressed = suppressedExceptions.length;if (numSuppressed > 0){err.println("\tThere are " + numSuppressed + " suppressed exceptions:");for (final Throwable exception : suppressedExceptions){err.println("\t\t" + exception.toString());}}}}
}

上面的应用程序将打印出所有抑制的异常。 在这种情况下,尝试关闭NaughtyResource时遇到的异常现在显示为被抑制的异常之一。 下一个屏幕快照对此进行了演示。

如Java教程中所述,我们看到唯一抛出的异常是在try-with-resources语句的try块中遇到的异常,并且在资源关闭期间遇到的第二个异常被“抑制”(但仍可从实际抛出异常)。

不需要使用try-with-resources来处理抑制的异常。 下一个代码清单将SuppressedExceptions改编为使用更传统的try-finally。

SuppressedExceptions.java(版本3)

package dustin.examples;import static java.lang.System.err;/*** Demonstrate JDK 7's Suppressed Exceptions API support.* * @author Dustin*/
public class SuppressedExceptions
{/*** Method that uses NaughtyResource with JDK 7 try-with-resource statement.* * @throws Exception Expected exception for try-with-resource used on the*    NaughtyResource.*/public static void performTryWithResource() throws Exception{try (NaughtyResource naughty = new NaughtyResource()){naughty.doNothingGood();}  }/*** Method that uses NaughtyResource with traditional try-finally statement.* * @throws Exception Exception thrown during use of NaughtyResource.*/public static void performTryFinally() throws Exception{final NaughtyResource naughty = new NaughtyResource();try{naughty.doNothingGood();}finally{naughty.close();}}/*** Executable function demonstrating suppressed exceptions.* * @param arguments The command line arguments; none expected.*/public static void main(String[] arguments){try{
//         performTryWithResource();performTryFinally();}catch (Exception ex){err.println("Exception encountered: " + ex.toString());final Throwable[] suppressedExceptions = ex.getSuppressed();final int numSuppressed = suppressedExceptions.length;if (numSuppressed > 0){err.println("\tThere are " + numSuppressed + " suppressed exceptions:");for (final Throwable exception : suppressedExceptions){err.println("\t\t" + exception.toString());}}else{err.println("\tNo Suppressed Exceptions.");}}}
}

上面的代码调用了一种使用try-finally的方法,其行为与try-with-resources示例的行为不同,如下面的屏幕快照所示。

try-finally显示尝试关闭资源时遇到的异常,而不是使用资源时遇到的异常(上面显示的try-with-resources相反)。 另一个不同之处是,即使在try-finally情况下,作为抑制的异常,其他异常也不可用。 这是一个广为宣传的 “ 丢失的异常 ”问题的示例 ,该问题可能包含潜在的“琐碎”异常(关闭资源),而隐藏了潜在的更重要的异常(实际上是在使用资源)。

如果我想同时查看NaughtyResource的使用和关闭过程中引发的异常以及try-finally,可以使用Throwable.addSuppressed(Throwable) ,如下面的代码清单所示。 在该清单中,对try和finally子句进行了增强,以捕获使用NaughtyResource期间引发的异常,并将捕获的异常添加到实际抛出的异常中作为抑制的异常。

SuppressedExceptions.java(版本4)

package dustin.examples;import static java.lang.System.err;/*** Demonstrate JDK 7's Suppressed Exceptions API support.* * @author Dustin*/
public class SuppressedExceptions
{/*** Method that uses NaughtyResource with JDK 7 try-with-resource statement.* * @throws Exception Expected exception for try-with-resource used on the*    NaughtyResource.*/public static void performTryWithResource() throws Exception{try (NaughtyResource naughty = new NaughtyResource()){naughty.doNothingGood();}  }/*** Method that uses NaughtyResource with traditional try-finally statement.* * @throws Exception Exception thrown during use of NaughtyResource.*/public static void performTryFinally() throws Exception{final NaughtyResource naughty = new NaughtyResource();Throwable throwable = null;try{naughty.doNothingGood();}catch (Exception usingEx){throwable = usingEx;}finally{try{naughty.close();}catch (Exception closingEx){if (throwable != null){closingEx.addSuppressed(throwable);throw closingEx;}}}}/*** Executable function demonstrating suppressed exceptions.* * @param arguments The command line arguments; none expected.*/public static void main(String[] arguments){try{
//         performTryWithResource();performTryFinally();}catch (Exception ex){err.println("Exception encountered: " + ex.toString());final Throwable[] suppressedExceptions = ex.getSuppressed();final int numSuppressed = suppressedExceptions.length;if (numSuppressed > 0){err.println("\tThere are " + numSuppressed + " suppressed exceptions:");for (final Throwable exception : suppressedExceptions){err.println("\t\t" + exception.toString());}}else{err.println("\tNo Suppressed Exceptions.");}}}
}

修改后的类的输出如下所示。 注意,由于使用资源本身而导致的异常现在与作为抑制的异常而引发的异常相关联。 尽管此处未显示,但Throwable现在还提供了一个构造函数,该构造函数允许通过布尔参数指定新实例化的Throwable是否允许(启用)抑制的异常(禁止)。

查看抑制异常的另一个角度是完整堆栈跟踪。 以下三幅图像是使用try-with-resources(显式显示假定的异常),使用传统的try-finally语句而未显式添加抑制的异常(因此在full stack跟踪中没有抑制的异常)导致的完整堆栈跟踪的屏幕快照。 ,并使用传统的try-finally方法,并明确添加抑制的异常(因此确实会出现在完整堆栈跟踪中)。 我在每个图像上都添加了一条红线,以单独显示整个堆栈跟踪结束的位置,并在适用的情况下,圈出了对抑制异常的显式引用。

抑制的异常与链接的异常

禁止的异常与链接的异常不同 。 链接异常是JDK 1.4引入的,旨在使轻松跟踪异常之间的因果关系成为可能。 通常,链接的异常是由于将新引发的异常与已捕获并导致引发新异常的异常相关联而导致的。 例如,可能会引发未检查的异常,从而“包装”已捕获的已检查的异常,并且可以将它们链接在一起。

JDK 7引入了抑制的异常,它与因果关系无关,而与在单个抛出的异常中表示可能相关但不一定因果的多个例外条件有关。 在上面的我的顽皮资源示例中,顽皮资源在其唯一方法被调用时的异常并不是导致它在调用其close方法时引发异常的原因。 因此,将两个异常关联起来(通过抑制的异常机制)比强迫一个异常似乎是造成连锁关系中另一个异常的原因更有意义。

通过比较Throwable访问每种类型的方法,最快速地了解链式异常与抑制型异常之间的区别可能是最容易的。 对于链式异常,将调用特定的Exception(Throwable)方法。 此方法返回导致Throwable的单个实例。 可以询问返回的Throwable的原因,并在导致Throwables的整个过程中重复该过程。 重要的观察结果是,每个给定的Throwable都有一个导致Throwable的原因。 这可以与Throwable在调用其getSuppressed()方法时提供多个抑制的Throwable(在数组中)的能力进行对比。

NetBeans推荐尝试资源

在此值得注意的是,NetBeans会警告您尝试使用try-finally,并建议使用try-with-resources替换它,如我在我的文章《 用于现代化Java代码的七个NetBeans提示》和下面显示的屏幕快照中所讨论的。

结论

我相信很明显,为什么NetBeans建议开发人员将对资源处理的最后尝试更改为try-with-resources语句。 通常最好先了解资源上的哪个操作导致了异常,但是如果需要的话,也能够在关闭时访问异常是很不错的。 如果必须选择,我通常会对执行期间的资源问题更感兴趣,因为关闭问题可能是该问题的衍生形式。 但是,两者都更好。 传统的try-finally最终仅列出关闭时的异常,而无需付出额外的努力来中继这两者。 try-with-resource语句不仅更简洁; 由于内置支持包含抑制的异常,它也更加有用。

参考: JCG合作伙伴 Dustin Marx在Inspired by Actual Events博客上提供了Java 7对抑制异常的支持 。


翻译自: https://www.javacodegeeks.com/2012/04/java-7s-support-for-suppressed.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373171.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

易于使用的单位和集成代码

此示例说明如何使用Maven和Sonar生成单元测试和集成测试的覆盖率。 它使用非常简单的技术,只需10-15分钟即可在任何现有的Maven构建中运行。 它可用于单元,集成,ATDD或任何其他类型的测试套件。 覆盖率结果显示在Sonar中。 有什么事吗&#x…

Ubuntu 16.04 安装 VMware-Workstation-12

以前一直使用 Ubuntu Virtaulbox ,最近测试了 VMware-Workstation-9,性能超过 Virtaulbox-4.2.x,下面是详细步骤:1 首先准备一个Ubuntu 系统 lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04 LTS Release: 16.04 …

SSH实战 · 唯唯乐购项目(中)

用户模块三:一级分类的查询创建一级分类表并导入基本数据CREATE TABLE category (cid int(11) NOT NULL AUTO_INCREMENT,cname varchar(255) DEFAULT NULL,PRIMARY KEY (cid)) ENGINEInnoDB AUTO_INCREMENT11 DEFAULT CHARSETutf8;建包及相应的类:com.weiwei.shoppi…

Android的IPC机制(一)——AIDL的使用

综述 IPC(interprocess communication)是指进程间通信,也就是在两个进程间进行数据交互。不同的操作系统都有他们自己的一套IPC机制。例如在Linux操作系统中可以通过管道、信号量、消息队列、内存共享、套接字等进行进程间通信。那么在Android系统中我们可以通过Bin…

Netty:透明地使用SPDY和HTTP

大多数人已经从谷歌那里听说过SPDY,该协议被提议作为老化的HTTP协议的替代品。 Web服务器是浏览器正在缓慢地实现该协议,并且支持正在增长。 在最近的文章中,我已经写过SPDY的工作方式以及如何在Jetty中启用SPDY支持。 由于Netty(…

selenium 等待页面加载完成

一、隐形加载等待&#xff1a; file:///C:/Users/leixiaoj/Desktop/test.html 该页面负责创建一个div <html> <head><title>Set Timeout</title><style>.red_box {background-color: red; width 20%; height:100px; border: none;}</style&…

linux nfsnobody用户,处理CentOS 5.5 x64 配置NFS服务过程中nfsnobody用户造成的问题

4、我们编译一下这个NFS的配置文件。[rootNFS /]# vi /etc/exports/share 192.168.60.0/24(rw,sync,all_squash,root_squash) (我们允许这个共享对192.168.60.0/24网段可读可写&#xff0c;且将所有访问者包括root的身份都改为nfsnobody)[rootNFS /]# /etc/init.d/nfs resta…

c语言空格有什么作用,空格在c语言中怎么表示 C语言中的空格字符怎么表示

c语言中表示空格的是什么代码&#xff1f;分析如下&#xff1a; 不是所有字符都需要转义的&#xff0c;空格直接就敲空格&#xff0c;或者使用ASCII码值赋值为32。 空格没有转义字符。合法转义字符如下&#xff1a;\a 响铃(BEL) 、\b 退格(BS)、\f 换页(FF)、\n 换行(LF)、\r 回…

StringMVC 中如何做数据校验

步骤一&#xff1a;引入四个jar包 步骤二&#xff1a;注册类型转换器 <context:component-scan base-package"cn.happy.controller"></context:component-scan><!-- 配置验证器 --><bean id"myvalidator" class"org.springframe…

ibm+x3650+m4+linux+raid驱动,IBM X3650M4阵列卡驱动下载

ibm X3650M4raid阵列卡驱动适合安装windowsserver2008,windowsserver2008R2,系统问题&#xff0c;服务器问题&#xff0c;可以联系我们也可以到5分享论坛发帖求助。IBM System x3650 M4服务器是一款应用最为广泛的2U机架服务器&#xff0c;支持Xeon E5-2600机架服务器的所有产品…

UML类图与类的关系详解

在画类图的时候&#xff0c;理清类和类之间的关系是重点。类的关系有泛化(Generalization)、实现&#xff08;Realization&#xff09;、依赖(Dependency)和关联(Association)。其中关联又分为一般关联关系和聚合关系(Aggregation)&#xff0c;合成关系(Composition)。下面我们…

python之路-SQLAlchemy

SQLAchemy SQLAlchemy是Python编程语言下的一款ORM框架&#xff0c;该框架建立在数据库API之上&#xff0c;使用关系对象映射进行数据库操作&#xff0c;简言之便是&#xff1a;将对象转换成SQL&#xff0c;然后使用数据API执行SQL并获取执行结果。 安装&#xff1a; pip3 inst…

Linux中vim编辑器的缩进的功能键

vim编程时,经常需要对代码进行缩进处理,以增加程序的可读性和后期的代码维护. 可以采用多种方式达到缩进的目的: 1) 命令模式(command mode) 2) Visual模式&#xff08;visual mode&#xff09; 2) 输入模式(entry mode) 3) 末行模式(last-line mode) 4) 在/etc/vimrc有给予vim…

JSF 2,PrimeFaces 3,Spring 3和Hibernate 4集成项目

本文展示了如何集成JSF2&#xff0c;PrimeFaces3&#xff0c;Spring3和Hibernate4技术。 它为Java开发人员提供了一个通用的项目模板。 另外&#xff0c;如果Spring不用于业务和数据访问层&#xff0c;则可以提供JSF – PrimeFaces和Hibernate集成项目。 二手技术&#xff1a…

初识openstack

一、 什么是openstack&#xff1f; OpenStack是一个由NASA&#xff08;美国国家航空航天局&#xff09;和Rackspace合作研发并发起的&#xff0c;以Apache许可证授权的自由软件和开放源代码项目。 二、openstack前世今身 openstack是一个跟Eucalyptus,AWS(Amazon web Service)类…

Arquillian 1.0.0.Final正式发布! 准备使用GlassFish和WebLogic! 杀死所有虫子!

红帽公司和JBoss社区今天宣布的1.0.0.Final发布的Arquillian &#xff0c;其屡获殊荣的建在Java虚拟机&#xff08;JVM&#xff09;运行测试平台。 Arquillian大大减少了编写和执行Java中间件集成和功能测试所需的工作。 它甚至使测试工程师能够解决以前认为无法测试或测试成本…

qq五笔linux,QQ五笔 - 五笔小字典 QQ绑定很实用

九、 智能调频、空码检索、词序固定在QQ五笔中还有一些小亮点&#xff0c;比如它可以根据“最近输入”、“输入次数”对候选词排序。同时为了加快检索速度&#xff0c;默认只在常用字库(GB2312)中检索&#xff0c;只有出现空码后才会继续搜索容量更大的GBK字库&#xff0c;很好…

android 关闭蓝牙打电话功能,Android蓝牙开发【八】hfp接听、挂断电话

继续研究hfp相关功能。蓝牙耳机可以控制手机接听、拒接、挂断电话&#xff0c;拨打电话等功能。本文主要分析下起这些操作的大致流程。在系统应用Bluetooth中com_android_bluetooth.cpp提供了多个回调方法&#xff0c;由hardware、协议栈回调过来。蓝牙耳机的一些控制命令都会发…

将状态机模式实现为流处理器

在我的上一个博客中&#xff0c;我说我真的以为某些“四人行”&#xff08;GOF&#xff09;模式已经过时了&#xff0c;如果不是过时的话肯定不受欢迎。 特别是我说过StateMachine不是那么有用&#xff0c;因为您通常会想到另一种更简单的方式来执行您正在执行的事情&#xff0…

android 自定义actionbar,如何让android的actionbar浮动且透明

如上图所示&#xff0c;谷歌地图的actionbar是透明的&#xff0c;且浮动在整个布局之上&#xff0c;没有占用布局空间。其实要做到这样的效果&#xff0c;我们首先想到的是两个方面&#xff1a;1.将让actionbar浮动起来。2.给actionbar一个背景&#xff0c;可以为颜色也可以为图…