如果所有呼叫者确保关闭它,我是否需要在准备好的语句创建上尝试使用资源?

时间:2018-02-07 23:41:06

标签: java prepared-statement try-with-resources

我正在使用一些遗留代码,它看起来像这样:

    PreparedStatement prepared_statement;
    if (x > 0) {
        prepared_statement = connect.prepareStatement(sql_query);
        prepared_statement.setInt(1, id);

        for (int i = 0; i < list_size; i++) {
            String internal_token_symbol = callMethod(coin, exchange_list.get(i));
        }
    } else {
        prepared_statement = connect.prepareStatement(sql_query);
        prepared_statement.setInt(1, token_id);
    }

    return prepared_statement;

这里的关键是它创建一个预准备语句,然后返回它以供以后使用。请注意,如果发生异常,它不使用try-with-resource或关闭。

我的问题是,如果此方法的每个调用者都使用了try-with-resource,那么是否存在未能关闭语句的危险?例如如果所有来电者都这样做:

try (PreparedStatement ps = resultOfCallingMyMethod()) {
   // Use the prepared statement
}

我这样做证明了这一点:

@Test
public void testIPrint() throws IOException { // this prints
    try (MyCloseable closeable = new MyCloseable()) {

    }
}

@Test
public void testIAlsoPrint() throws IOException, InterruptedException { //this doesn't print :(
    try (MyCloseable closeable = iThrowAnException()) {

    }
}

private MyCloseable iThrowAnException() {
    MyCloseable closeable = new MyCloseable();
    if (true) {
        throw new RuntimeException();
    }
    return closeable;
}

public static class MyCloseable implements Closeable {
    @Override
    public void close() throws IOException {
        System.out.println("I was closed!");
    }
}

1 个答案:

答案 0 :(得分:4)

不,这没关系,唯一的问题是:如何确保每个调用者都在使用try-with-resource?

通常,我尽量不要在课堂外泄漏PreparedStatement。通过这种方式,关闭它仍然是责任。

编辑:按照Mike Strobel的评论Actualy:如果x > 0callMethod引发异常,则不会将其返回给来电者并赢得&# 39;关闭。