首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在try-with-resources中为空检查

在try-with-resources中为空检查
EN

Stack Overflow用户
提问于 2020-02-28 22:37:24
回答 2查看 651关注 0票数 0

我得到了以下代码:

代码语言:javascript
复制
try (Connection connection = getConnection();

    PreparedStatement preparedStatement = connection.prepareStatement(someSql)) {//stuff}

我如何检查这里的连接是否不为空?

另外,我还得到了一个返回PreparedStatement的方法,如下所示:

代码语言:javascript
复制
private PreparedStatement getPreparedStatement(Connection connection)

  throws SQLException {

PreparedStatement preparedStatement = connection.prepareStatement(SQL);

preparedStatement.setString(1, "someString");

return preparedStatement;

}

在对资源使用以下try的方法中调用此方法:

代码语言:javascript
复制
try (Connection connection = getConnection();
    PreparedStatement preparedStatement =
        getPreparedStatement(connection)) {//stuff}

现在,我假设准备好的语句将自动关闭,因为它是在try with resources中启动的。但是SonarCloud说我应该在getPreparedStatement- PreparedStatement方法中对资源使用try,或者在finally块中关闭该try。这是SonarCloud的错误发现,还是有更好的方法呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-28 22:41:28

getConnection应该抛出异常,而不是返回null。返回null不是nice. SonarCloud seems to be wanting you to put a try-with-resource opening ingetPreparedStatement(must include thesetString`),也不是在调用方法中关闭,这当然不能这样做。

最好的方法是Execute Around idiom。而不是在要执行的lambda (通常)中返回PreparedStatement传递。然后,可以在try-with-resource语句中干净利落地关闭资源。

代码语言:javascript
复制
/*** NICE ***/
// Function instead of Consumer would allow the method to return a value.
private void prepared(
    Connection connection, Consumer<PreparedStatement> op
) throws SQLException {
    // Might want to add getConnection in here too, perhaps.
    try (
        PreparedStatement statement =
             connection.prepareStatement(SQL)
    ) { 
        statement.setString(1, "someString");
        op.accept(statement);
    }
}

用作:

代码语言:javascript
复制
    try (Connection connection = getConnection()) {
        prepared(connection, statement -> {
            // blah, blah, blah
        });
    }

另一种方法是在getPreparedStatement中包含一条try语句,该语句只在错误条件下关闭。

代码语言:javascript
复制
/*** HACKY ***/
private PreparedStatement prepared(
    Connection connection
) throws SQLException {
    boolean success = false;
    PreparedStatement statement =
        connection.prepareStatement(SQL);
    try { 
        statement.setString(1, "someString");
        success = true;
        return preparedStatement;
    } finally {
        if (!success) {
            statement.close();
        }
    }
}

如果您非常希望getConnection返回null (不要)并使用一个两个条目的try-with-resource,那么条件运算符是有效的。

代码语言:javascript
复制
try (
    Connection connection = getConnection();
    PreparedStatement statement =
        connection==null ? null : connection.prepareStatement(SQL)
) {
票数 1
EN

Stack Overflow用户

发布于 2020-02-28 22:59:46

最简单的方法和最具可读性的方法是使用2个try-with-resources块。甚至声纳也有一个内置的例外,不允许嵌套的try-catch块用于这种用例……

代码语言:javascript
复制
try (Connection conn = getConnection()) {
    if (conn != null) {
        try (PreparedStatement stmt = ...) {
            // do stuff
        }
    }
}

如果do stuff很长,那么可以而且应该将其重构为一个单独的方法(可能包括内部的try-with-resources)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60453893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档