繁体   English   中英

Break无法尝试使用资源,但无法尝试使用资源

[英]Break doesn't work in try with resources, but work in try without resources

歇不尝试用资源的工作,但没有资源在试运行!
这是这种情况的一个简单示例。 我在工作项目中发现了这个“ bug”。 当我使用没有资源的尝试

try {
Resources resources = getResources()
// some code here, look below
}

我的循环只有一个迭代,这是正确的,因为我的条件是“如果为真,然后中断”,但是当我更改时,尝试不使用try 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();
            }
        }

循环是无止境的,因为您的关闭发生在try范围的末尾。 这将引发异常,从而中断中断操作。 然后,异常处理程序(在while循环内部)捕获它,并继续到循环结束,并且由于循环条件为“ true”,因此永远持续下去。 当您不使用try-with-resource时,永远不会调用close,因此不会引发异常,并且中断不会中断。

在执行break之前,将调用Resource上的close方法。 可以在字节码中看到:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM