Break不会尝试使用资源,但可以尝试使用 而无需 资源! 这是这种情况的一个简单示例。我抓住了这个" bug"在工作项目中。 当我使用没有资源的尝试时
try {
Resources resources = getResources()
// some code here, look below
}
我的循环只有一次迭代,而且它是正确的,因为我有条件"如果是真的那么打破",但是当我改变尝试没有求助尝试WITH资源。
try (Resources resources = getResources()) {
// some code here, look below
}
我很震惊!循环变得无穷无尽!为什么呢?
完整代码:
public class Test {
public static void testTryWithResAndBreak() {
while (true) {
System.out.println("we are in (while(true))");
try (Resources resources = getResources()) {
System.out.println("We are in try block");
if (true) {
System.out.println("We are in the if(true) now! Next step is break");
break;
}
System.out.println("OOOOO___OOOO WE ARE HERE!!!");
resources.writeSomething();
} catch (Exception e) {
System.out.println("Catched exception");
}
}
}
private static class Resources implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("Resources closed");
throw new Exception("Exception after closed resources!");
}
public void writeSomething() {
System.out.println("i wrote something");
}
}
private static Resources getResources() {
return new Resources();
}
public static void main(String[] args) {
testTryWithResAndBreak();
}
}
答案 0 :(得分:1)
循环是无止境的,因为你的结束发生在try范围的末尾。这会抛出异常,从而中断中断操作。异常处理程序(在while循环中INSIDE)然后捕获它,并继续循环结束,并且因为循环条件是“真实”,所以永远继续。如果您不使用try-with-resource,则不会调用close,因此不会抛出异常,并且不会中断中断。
答案 1 :(得分:0)
在break
执行之前,close
上的Resource
方法被调用。这可以在字节代码中看到:
L9 // Print statement
LINENUMBER 14 L9
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "We are in the if(true) now! Next step is break"
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L1 // Close method call
LINENUMBER 17 L1
ALOAD 2
IFNULL L10
ALOAD 2
INVOKEVIRTUAL Main$Resources.close ()V
L3 // Then the break
LINENUMBER 15 L3
GOTO L10
但是这个close
方法本身会抛出一个异常,它将控制转移到catch
块。 catch
块完成后,while
循环继续下一次迭代。所以永远不会执行break
语句。
try-with-resources生成的结构如下所示:
try {
Resources resources = null;
try {
resources = getResources();
if (true) {
break;
}
} catch (Exception e) {
} finally {
if(resources != null)
resources.close();
}
} catch (Exception e) {
}
这与您的版本不同,内部finally
块已经处理了异常,之后执行break
。但是在上面,异常由外部catch
块处理,之后控制返回到while
循环。