在下面的代码示例中,我希望 1 作为方法 testM()
的返回值。但由于 TestAutoCloseable.close()
方法中的异常,我得到了意外的行为。
我的问题是:“这是 JVM 的正常行为吗?”
public static void main(String[] args) {
ProgrammerTwo programmerTwo = new ProgrammerTwo();
System.out.println(programmerTwo.testM());
}
int testM() {
try (TestAutoCloseable closable = new TestAutoCloseable()) {
System.out.println("Do first return");
return 1;
} catch (IOException e) {
System.out.println("handled");
}
System.out.println("Do something, that shouldn't do if first return have happened");
return 2;
}
static class TestAutoCloseable implements AutoCloseable {
@Override
public void close() throws IOException {
throw new IOException();
}
}
因为如果这是正常行为,我们不应该在 try with resources 语句中使用 return 或 break 语句。它应该是反模式。
最佳答案
有关 try-with-resources
语句如何工作的详细信息位于 this section来自 JLS。在您的情况下,它是一个 扩展 try-with-resources
因为它有一个 catch
子句,如下面的引用中所定义(请注意突出显示的声明在最后)。
A try-with-resources statement with at least one catch clause and/or a finally clause is called an extended try-with-resources statement.
The meaning of an extended try-with-resources statement:
try ResourceSpecification Block [Catches] [Finally]
is given by the following translation to a basic try-with-resources statement nested inside a try-catch or try-finally or try-catch-finally statement:
try {
try ResourceSpecification <--- exception thrown in this basic try-with-resources
Block
}
[Catches]
[Finally]
The effect of the translation is to put the resource specification "inside" the try statement. This allows a catch clause of an extended try-with-resources statement to catch an exception due to the automatic initialization or closing of any resource.
这意味着关闭资源发生在外部 try
block 的主体内,导致抛出异常并在 catch
中进行处理> block ,控制权恢复到扩展 try-with-resources
语句之后的语句。
实际上,整个方法 testM
相当于:
int testM() {
try {
final TestAutoCloseable closable = new TestAutoCloseable();
Throwable #primaryExc = null;
try {
System.out.println("Do first return");
return 1;
} catch (Throwable #t) {
#primaryExc = #t;
throw #t;
} finally {
if (closable != null) {
if (#primaryExc != null) {
try {
closable.close();
} catch (Throwable #suppressedExc) {
#primaryExc.addSuppressed(#suppressedExc);
}
} else {
closable.close();
}
}
}
} catch (IOException e) {
System.out.println("handled");
}
System.out.println("Do something, that shouldn't do if first return have happened");
return 2;
}
关于java - 返回尝试资源。这是 JVM 的正确行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39595742/