soc到answer的评论(由用户a question about tail call optimisation)提到Java 7有一个名为“抑制异常”的新功能,因为“添加了ARM”(支持ARM CPU?)。
在这种情况下,什么是“抑制异常”?在其他情况下,“被抑制的异常”将是一个被捕获然后被忽略的异常(很少是一个好主意);这显然是不同的。
答案 0 :(得分:55)
为了澄清Jon的答案中的引用,一个方法只能抛出一个异常(每次执行),但在try-with-resources
的情况下,有可能抛出多个异常。例如,可能会在块中抛出一个,而另一个可能会从finally
提供的隐式try-with-resources
抛出。
编译器必须确定哪些“真正”抛出。它选择抛出在显式代码(try
块中的代码)中引发的异常,而不是隐式代码(finally
块)抛出的异常。因此,隐式块中抛出的异常被抑制(忽略)。这仅在多个例外的情况下发生。
答案 1 :(得分:48)
我认为评论者指的是一个异常,当它被抛出try-with-resources块的隐式finally
块内时,在从现有异常抛出的上下文中被忽略。 try
阻止:
可以从与try-with-resources语句关联的代码块中抛出异常。在示例writeToFileZipFileContents中,可以从try块抛出异常,并且当try-with-resources语句尝试关闭ZipFile和BufferedWriter对象时,最多可以抛出两个异常。如果从try块抛出异常并且从try-with-resources语句抛出了一个或多个异常,那么从try-with-resources语句抛出的那些异常将被抑制,并且块抛出的异常是这是由writeToFileZipFileContents方法抛出的。您可以通过从try块抛出的异常中调用Throwable.getSuppressed方法来检索这些抑制的异常。
(这是从链接页面引用一个名为“抑制异常”的部分。)
答案 2 :(得分:13)
在Java7之前;代码中抛出异常,但在某种程度上被忽略了。
e.g。)
public class SuppressedExceptions {
public static void main(String[] args) throws Exception {
try {
callTryFinallyBlock();
} catch (Exception e) {
e.printStackTrace(); **//Only Finally Exception is Caught**
}
}
private static void callTryFinallyBlock() throws Exception {
try
{
throw new TryException(); **//This is lost**
}
finally
{
FinallyException fEx = new FinallyException();
throw fEx;
}
}
}
class TryException extends Exception {
}
class FinallyException extends Exception {
}
在JDK 7中的Throwable类中添加了一个新的构造函数和两个新方法。 具体如下:
Throwable.getSupressed(); // Returns Throwable[]
Throwable.addSupressed(aThrowable);
使用这种新方法,我们也可以处理那些被抑制的异常。
public class SuppressedExceptions {
public static void main(String[] args) throws Exception {
try {
callTryFinallyBlock();
} catch (Exception e) {
e.printStackTrace();
for(Throwable t: e.getSuppressed())
{
t.printStackTrace();
}
}
}
private static void callTryFinallyBlock() throws Exception {
Throwable t = null;
try
{
throw new TryException();
}
catch (Exception e) {
t = e;
}
finally
{
FinallyException fEx = new FinallyException();
if(t != null)fEx.addSuppressed(t);
throw fEx;
}
}
}
class TryException extends Exception {
}
class FinallyException extends Exception {
}
在Java7中试用资源; AutoCloseable :: close()中的异常 默认情况下会添加为抑制异常以及尝试异常。
同时意识到这与chained exceptions不同(在JDK 1.4中引入,旨在使得可以轻松跟踪异常之间的因果关系。)
答案 3 :(得分:9)
Suppressed exceptions是在introduced in Java 7资源关闭时在try-with-resources语句(AutoCloseable
)内发生的其他异常。由于在关闭AutoCloseable
资源时可能会出现多个例外情况,因此primary exception as suppressed exceptions会附加其他例外情况。
查看一段try-with-resources示例代码的字节码,标准JVM exception handlers用于容纳try-with-resources语义。
答案 4 :(得分:6)
隐藏下面的代码:
public class MultipleExceptionsExample {
static class IOManip implements Closeable{
@Override
public void close() {
throw new RuntimeException("from IOManip.close");
}
}
public static void main(String[] args) {
try(IOManip ioManip = new IOManip()){
throw new RuntimeException("from try!");
}catch(Exception e){
throw new RuntimeException("from catch!");
}finally{
throw new RuntimeException("from finally!");
}
}
}
您将获得所有行:java.lang.RuntimeException: from finally!
删除finally
阻止,您将获得:java.lang.RuntimeException: from catch!
删除catch
阻止,您将获得:
Exception in thread "main" java.lang.RuntimeException: from try!
Suppressed: java.lang.RuntimeException: from IOManip.close
答案 5 :(得分:0)
我认为这与“链式异常工具”有关。随着堆栈跟踪的发展,它将影响此工具处理异常的方式。随着时间的推移,可以抑制属于一组链式异常的异常。请查看the Throwable documentation了解更多详情。
答案 6 :(得分:0)
ARM - 自动资源管理(自Java 7以来推出)
举一个非常简单的例子
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
现在,如果readLine()
函数抛出异常,然后偶数close()
函数[在finally块中]抛出异常,则后者被赋予更多优先级并被抛回到调用函数。在这种情况下Exception thrown by the readLine() method is ignored/suppressed
。您可以在异常中链接导致异常,并从finally块重新抛出异常。
由于提供了java 7
功能来检索已抑制的异常。您可以在catched throwable对象上调用public final java.lang.Throwable[] getSuppressed()
函数来查看被抑制的异常。
对于例如。
static String readFirstLineFromFileWithFinallyBlock(String path)
throws Exception {
try (BufferedReader br = new BufferedReader(new FileReader(path));) {
return br.readLine();
}
}
现在,如果br.readLine();
行抛出Exception1
,然后在关闭资源时抛出Exception2
[想象一下,在try-with-resource语句创建的隐式finally块中发生这种情况]然后Exception1抑制Exception2。
这里有几点需要注意 -
我已经使用以下帖子编写了代码片段和输出的大部分可能方案。
Suppressed exceptions in java 7
希望有所帮助。
答案 7 :(得分:0)
您也可以在Java 6中抑制异常(涉及一些小技巧),
我创建了一个透明地处理Java 1.6和Java 1.7中的异常处理的实用程序。您可以找到实施here
您只需致电:
public static <T extends Throwable> T suppress(final T t, final Throwable suppressed)
压制异常,
public static Throwable [] getSuppressed(final Throwable t) {
获取异常的抑制异常,以防任何人仍然使用Java 1.6