在java中尝试使用资源和返回语句

maf*_*aff 37 java return try-with-resources

我想知道在try-with-resources块中放置一个return语句是否会阻止资源自动关闭.

try(Connection conn = ...) {
    return conn.createStatement().execute("...");
}
Run Code Online (Sandbox Code Playgroud)

如果我写这样的东西将关闭连接?在Oracle文档中,声明:

try-with-resources语句确保在语句结束时关闭每个资源.

如果由于返回语句而从未到达语句的结尾会发生什么?

mer*_*011 51

根据Oracle的教程,"[资源]将被关闭,无论try语句是正常完成还是突然完成".它定义abruptly为异常.

内部返回tryJLS 14.1定义的突然完成的示例.

  • 这在技术上并不正确.`return`语句没有正常完成,因此`try`块没有正常完成.它突然完成. (3认同)
  • 我在手机上:(.如果你在包含try catch块的章节中转到JLS,那么还有一个部分定义了通常意味着什么.查找返回语句的条目. (2认同)
  • @SotiriosDelimanolis,我找到了它并更新了我的答案。谢谢指正! (2认同)

Nur*_*tcu 11

资源将自动关闭(即使使用return语句),因为它实现了AutoCloseable接口.这是一个输出"成功关闭"的例子:

public class Main {

    public static void main(String[] args) {
        try (Foobar foobar = new Foobar()) {
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Foobar implements AutoCloseable {

    @Override
    public void close() throws Exception {
        System.out.println("closed successfully");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我刚刚测试了这个,是的,首先调用“close()”,然后您将得到一个关闭的对象作为返回值。 (4认同)
  • 那么,当您返回foobar时会发生什么呢?然后,您将返回一个“已经关闭”的Foobar实例吗? (2认同)

小智 7

AutoCloseable接口乍一看可能会使代码的执行顺序变得混乱。让我们用一个例子来解释一下:

public class Main {

    // An expensive resource which requires opening / closing
    private static class Resource implements AutoCloseable {

        public Resource() {
            System.out.println("open");
        }
        
        @Override public void close() throws Exception {
            System.out.println("close");
        }
    }
    
    // find me a number!
    private static int findNumber() {
        // open the resource
        try(Resource resource = new Resource()) {
            // do some business logic (usually involving the resource) and return answer
            return 2 + 2;
        } catch(Exception e) {
            // resource encountered a problem
            throw new IllegalStateException(e);
        }
    }
    
    public static void main(String[] args) {
        System.out.println(findNumber());
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码尝试Resource使用资源打开一些资源并执行一些业务逻辑(在本例中只是一些算术)。运行代码将打印:

open
close
4
Run Code Online (Sandbox Code Playgroud)

因此,Resource在退出 try-with-resource 块之前将其关闭。为了弄清楚究竟发生了什么,让我们重新组织一下该findNumber()方法。

    private static int findNumber() {
        // open the resource
        int number;
        try(Resource resource = new Resource()) {
            // do some business logic and return answer
            number = 2 + 2;
        } catch(Exception e) {
            // resource encountered a problem
            throw new IllegalStateException(e);
        }
        return number;
    }
Run Code Online (Sandbox Code Playgroud)

return从概念上讲,这就是将其放置在 try-with-resource 块中时在幕后发生的情况。该return操作被移至 try-with-resource 块之后,以允许AutoCloseable对象在返回之前关闭。

因此我们可以得出结论,returntry-with-resource 块内的操作只是语法糖,您不必担心在 anAutoCloseable关闭之前返回。