java - try-with-resources 中的 null 检查

标签 java try-catch try-with-resources null-check sonarcloud

我有以下代码:

try (Connection connection = getConnection();

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

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

另外,我有一个方法返回一个像这样的PreparedStatement:

private PreparedStatement getPreparedStatement(Connection connection)

  throws SQLException {

PreparedStatement preparedStatement = connection.prepareStatement(SQL);

preparedStatement.setString(1, "someString");

return preparedStatement;

}

这会在使用以下资源尝试的方法中调用:

try (Connection connection = getConnection();
    PreparedStatement preparedStatement =
        getPreparedStatement(connection)) {//stuff}

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

最佳答案

getConnection 应该抛出异常而不是返回 null。返回 null 不太好。 SonarCloud 似乎希望您在 getPreparedStatement 中放置一个 try-with-resource 开头(必须包含 setString`)并在调用方法中关闭,这当然是您不能做的就这样。

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

/*** 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);
    }
}

用作:

    try (Connection connection = getConnection()) {
        prepared(connection, statement -> {
            // blah, blah, blah
        });
    }

另一种方法是在 getPreparedStatement 中包含一个 try 语句,该语句仅在错误情况下关闭。

/*** 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,那么条件运算符就可以工作。

try (
    Connection connection = getConnection();
    PreparedStatement statement =
        connection==null ? null : connection.prepareStatement(SQL)
) {

关于java - try-with-resources 中的 null 检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60453893/

相关文章:

java - 如何连续运行Java jar?

java - IntelliJ IDEA 提示 "implicit numeric conversion of char to int"

java - android Intent 构造函数中 `this`和 `ActivityClass.this`有什么区别?

C# 在没有 try-catch block 的情况下重新抛出异常

python - 尝试使用except处理错误时出现SyntaxError

java - try-with-resources:Kotlin 中的 "use"扩展功能并不总是有效

java - 遵循 mkyong 指南后,Postgresql executeBatch 无法正常工作

java - C# 中的 Point2D.Double

c# - try{..}catch{...} 有 finally 和没有它的区别

java - 在 try-with-resource 中手动关闭