什么是抑制异常?
(用户soc)对回答一个关于尾部调用优化的问题提到Java 7由于“添加了 ARM”(支持 ARM CPU?),有一个名为“抑制异常”的新功能。
在这种情况下,什么是“受抑制的异常”?在其他情况下,“抑制的异常”是捕获然后忽略的异常(很少是一个好主意);这显然是不同的。
A comment (by user soc) on an answer to a question about tail call optimisation mentioned that Java 7 has a new feature called "suppressed exceptions", because of "the addition of ARM" (support for ARM CPUs?).
What is a "suppressed exception" in this context? In other contexts a "suppressed exception" would be an exception that was caught and then ignored (rarely a good idea); this is clearly something different.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
Java7之前;代码中抛出了异常,但不知何故被忽略了。
例如)
JDK 7 中的 Throwable 类中添加了一个新的构造函数和两个新方法。
这些如下:
通过这种新方法,我们也可以处理那些被抑制的异常。
另请注意,这与链式异常不同(随 JDK 1.4 引入,旨在以便轻松跟踪异常之间的因果关系。)
Before Java7; There are exceptions thrown in the code but were ignored somehow.
e.g.)
A new constructor and two new methods were added to the Throwable class in JDK 7.
These are as below:
with this new approach, we can handle those suppressed exception as well.
Also aware that this is different from chained exceptions (were introduced with JDK 1.4 and were intended to make it possible to easily track causal relationships between exceptions.)
考虑到下面的代码:
对于所有行,您将得到:
java.lang.RuntimeException: from finally!
删除
finally
块,您将得到:java.lang.RuntimeException : from catch!
删除
catch
块,您将得到:Concedering the code below:
With all lines you will get:
java.lang.RuntimeException: from finally!
Removing
finally
block you will get:java.lang.RuntimeException: from catch!
Removing
catch
block you will get:抑制的异常 是 try-with-resources 语句中发生的其他异常 (在 Java 7 中引入)当
AutoCloseable
资源已关闭。由于关闭AutoCloseable
资源时可能会发生多个异常,因此将附加异常附加到 主要异常作为抑制异常。查看一段 try-with-resources 示例代码的字节码,标准 JVM 异常处理程序 用于适应 try-with-resources 语义。
Suppressed exceptions are additional exceptions that occur within a try-with-resources statement (introduced in Java 7) when
AutoCloseable
resources are closed. Because multiple exceptions may occur while closingAutoCloseable
resources, additional exceptions are attached to a primary exception as suppressed exceptions.Looking at the bytecode of a piece of try-with-resources sample code, standard JVM exception handlers are used to accommodate the try-with-resources semantics.
您也可以在 Java 6 中抑制异常(涉及一些技巧),
我创建了一个实用程序,可以透明地处理 Java 1.6 和 Java 1.7 中的抑制异常。您可以找到实现 这里
您所需要的只是调用:
抑制异常,并
获取异常的抑制异常,以防有人仍然使用 Java 1.6
You can suppress Exceptions in Java 6 as well (a little trickery involved),
I created a utility that transparently handles suppressing exception in Java 1.6 and Java 1.7. You can find the implementation here
All you need is to call:
to supress a exception, and
to get the suppressed exceptions of a Exception, in case anybody still uses Java 1.6
ARM - 自动资源管理(从 Java 7 开始引入)
举一个非常简单的例子
现在如果
readLine()
函数抛出异常,然后甚至close()
函数[在finally块中]抛出异常,然后后者被赋予更高的优先级并被扔回调用函数。在这种情况下,由 readLine() 方法抛出的异常将被忽略/抑制
。您可以将引发异常链接到异常中,并从finally 块中重新抛出异常。自
java 7
以来,已经提供了检索被抑制的异常的功能。您可以在捕获的 throwable 对象上调用 public final java.lang.Throwable[] getSuppressed() 函数来查看抑制的异常。对于例如。
现在,如果
br.readLine();
行抛出Exception1
,然后假设在关闭资源时抛出Exception2
[想象一下这发生在隐式finally 阻止 try-with-resource 语句创建],然后 Exception1 抑制 Exception2。这里有几点需要注意 -
我已经在下面的文章中使用代码片段和输出编译了大多数可能的场景。
java 7 中的抑制异常
希望有所帮助。
ARM - Automatic Resource Management(Introduced since Java 7)
Take a very simple example
Now if
readLine()
function throws Exception and then evenclose()
function [in finally block] throws exception then the later is given more priority and is thrown back to the calling function. In this case theException thrown by the readLine() method is ignored/suppressed
. You can chain the causing exception in your exception and rethrow your exception from finally block.Since
java 7
functionality has been provided to retrieve suppressed Exceptions. You can callpublic final java.lang.Throwable[] getSuppressed()
function on the catched throwable object to view the suppressed Exceptions.For Eg.
Now if
br.readLine();
line throwsException1
and then lets sayException2
is thrown while closing the resource [Imagine this happening in an implicit finally block that try-with-resource statement creates] then Exception1 suppresses Exception2.Few points to note here -
I have compiled most of the possible scenarios with code snippets and output in following post.
Suppressed exceptions in java 7
Hope that helps.
我认为这与“链式异常设施”有关。随着堆栈跟踪的发展,它将影响该工具处理异常的方式。随着时间的推移,作为一组链式异常的一部分的异常可以被抑制。有关更多详细信息,请参阅Throwable 文档。
I think this has to do with the "chained exception facility". It will affect how an exception is handled by this facility as the stack trace evolves. Over time exceptions that are part of a group of chained exception can be suppressed. Look at the Throwable documentation for more details.
为了澄清乔恩答案中的引用,一种方法(每次执行)只能抛出一个异常,但在
try-with-resources
的情况下,可能会抛出多个异常。例如,一个可能会被抛出到块中,另一个可能会从try-with-resources
提供的隐式finally
中抛出。编译器必须确定其中哪一个“真正”抛出。它选择抛出显式代码(
try
块中的代码)引发的异常,而不是隐式代码(finally
块)引发的异常。因此,隐式块中引发的异常将被抑制(忽略)。这只发生在多个异常的情况下。To clarify the quote in Jon's answer, only one exception can be thrown by a method (per execution) but it is possible, in the case of a
try-with-resources
, for multiple exceptions to be thrown. For instance one might be thrown in the block and another might be thrown from the implicitfinally
provided by thetry-with-resources
.The compiler has to determine which of these to "really" throw. It chooses to throw the exception raised in the explicit code (the code in the
try
block) rather than the one thrown by the implicit code (thefinally
block). Therefore the exception(s) thrown in the implicit block are suppressed (ignored). This only occurs in the case of multiple exceptions.我相信评论者指的是一个异常,当它在 try-with-resources 块,在从
try
块抛出现有异常的上下文中:(这是引用链接页面中名为“抑制的异常”的部分。)
I believe the commenter is referring to is an exception which is semi-ignored when it's thrown within the implicit
finally
block of a try-with-resources block, in the context of an existing exception being thrown from thetry
block:(That's quoting a section called "Suppressed Exceptions" from the linked page.)