休息并没有尝试使用资源,但是在没有资源的情况下尝试

时间:2016-09-29 17:58:02

标签: java try-catch try-with-resources

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();
            }
        }

2 个答案:

答案 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循环。