gpt4 book ai didi

java - Java SE7 中的异常抑制

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:42:16 25 4
gpt4 key购买 nike

我试图理解 Java SE7 中被抑制的异常,我在下面发布了 2 个示例,它们是相似的,在下面的示例中,我的印象是当新的“主要异常”发生时,被抑制的异常被忽略,因为例如,我期望输出为“java.lang.RuntimeException: y”,但答案是:

java.lang.RuntimeException: y
抑制 java.lang.RuntimeException: a

代码如下:

class Animal implements AutoCloseable{

@Override
public void close() {
throw new RuntimeException("a");
}
}

public class ExceptionsDemo {
public static void main(String[] args) throws IOException {

try(Animal a1 = new Animal();){
foo();
}
catch(Exception e){
System.err.println(e);
for(Throwable t : e.getSuppressed()){
System.err.println("suppressed "+ t);
}
}
}

static void foo() {
try {
throw new RuntimeException("x");
} catch (Exception e) {
throw new RuntimeException("y");
}
}
}

我的理解是,在 tryWithResources 子句之后,“a”是 main Exc,然后在 foo() 中,x 成为 main exc 而 a 被抑制,但在 catch 中,我认为 y 将成为单独的 main exc 并且会忽略所有其他异常,包括被抑制的异常?

像第二个例子,它做了我刚才提到的,它输出 java.lang.RuntimeException: c 没有被抑制的异常。

public class ExceptionDemo2 {

class Animal implements AutoCloseable{

@Override
public void close() {
throw new RuntimeException("a");
}
}

public static void main(String[] args) {
try{
new ExceptionDemo2().go();
}
catch(Exception e){
System.err.println(e);
for(Throwable t : e.getSuppressed()){
System.err.println("suppressed "+ t);
}
}
}

void go(){
try(Animal a = new Animal()){
throw new IOException();
}catch(Exception e){
throw new RuntimeException("c");
}
}

}

输出:java.lang.RuntimeException: c

最佳答案

你的例子

try(Animal a1 = new Animal();){
foo();
}
catch(Exception e){
System.err.println(e);
for(Throwable t : e.getSuppressed()){
System.err.println("suppressed "+ t);
}
}

因为 foo() 抛出 RuntimeException (y) 而终止。这就是 catch 的目标。因为执行离开了 try block ,所有声明的资源都被关闭。关闭 Animal 实例时,会抛出另一个 RuntimeException (a)。那个被压制是因为它不是根本原因。

try-with-resources 转换为 try-catch-finally block 在 JLS 中有解释,here .

The meaning of a basic try-with-resources statement:

try ({VariableModifier} R Identifier = Expression ...)
Block

is given by the following translation to a local variable declaration and a try-catch-finally statement:

{
final {VariableModifierNoFinal} R Identifier = Expression;
Throwable #primaryExc = null;

try ResourceSpecification_tail
Block
catch (Throwable #t) {
#primaryExc = #t;
throw #t;
} finally {
if (Identifier != null) {
if (#primaryExc != null) {
try {
Identifier.close();
} catch (Throwable #suppressedExc) {
#primaryExc.addSuppressed(#suppressedExc);
}
} else {
Identifier.close();
}
}
}
}

在哪里

If the resource specification declares one resource, then ResourceSpecification_tail is empty (and the try-catch-finally statement is not itself a try-with-resources statement).

你上面的代码基本上可以翻译成类似的东西

try {
final Animal a1 = new Animal();
Throwable thr = null;
try {
foo();
} catch (Throwable root) {
thr = root;
throw root;
} finally {
if (a1 != null) {
if (thr != null) {
try {
a1.close();
} catch (Throwable suppressed) {
thr.addSuppressed(suppressed); // <<<<<< suppressing the failure of 'close'
}
} else {
a1.close();
}
}
}
} catch (Exception e) {
System.err.println(e);
for (Throwable t : e.getSuppressed()) {
System.err.println("suppressed " + t);
}
}

关于java - Java SE7 中的异常抑制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34339925/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com