在 try-with-resources 中进行空检查
null check in try-with-resources
我有以下代码:
try (Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(someSql)) {//stuff}
如何检查这里的连接是否为空?
另外,我得到了一个 returns 像这样的 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 方法中尝试使用资源,或者在 finally 块中关闭该 PreparedStatement。这是 SonarCloud 的错误发现还是有更好的方法?
getConnection
应该抛出异常而不是 returning null
。返回 null
不好 . SonarCloud seems to be wanting you to put a try-with-resource opening in
getPreparedStatement(must include the
setString`) 并关闭调用方法,当然你不能这样做。
最好的方法是Execute Around idiom。而不是 getPreparedStatement
return 将 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
到 return null
(不要)并使用单个两次输入的 try-with-resource,则条件运算符有效。
try (
Connection connection = getConnection();
PreparedStatement statement =
connection==null ? null : connection.prepareStatement(SQL)
) {
最简单的方法和 IMO 最可读的方法是使用 2 个 try-with-resources 块。即使是声纳也有一个内置的例外,就是不允许嵌套的 try-catch-blocks 正是这个用例...
try (Connection conn = getConnection()) {
if (conn != null) {
try (PreparedStatement stmt = ...) {
// do stuff
}
}
}
如果 do stuff
很长,它可以而且应该重构为一个单独的方法(可能包括内部 try-with-resources)。
我有以下代码:
try (Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(someSql)) {//stuff}
如何检查这里的连接是否为空?
另外,我得到了一个 returns 像这样的 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 方法中尝试使用资源,或者在 finally 块中关闭该 PreparedStatement。这是 SonarCloud 的错误发现还是有更好的方法?
getConnection
应该抛出异常而不是 returning null
。返回 null
不好 . SonarCloud seems to be wanting you to put a try-with-resource opening in
getPreparedStatement(must include the
setString`) 并关闭调用方法,当然你不能这样做。
最好的方法是Execute Around idiom。而不是 getPreparedStatement
return 将 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
到 return null
(不要)并使用单个两次输入的 try-with-resource,则条件运算符有效。
try (
Connection connection = getConnection();
PreparedStatement statement =
connection==null ? null : connection.prepareStatement(SQL)
) {
最简单的方法和 IMO 最可读的方法是使用 2 个 try-with-resources 块。即使是声纳也有一个内置的例外,就是不允许嵌套的 try-catch-blocks 正是这个用例...
try (Connection conn = getConnection()) {
if (conn != null) {
try (PreparedStatement stmt = ...) {
// do stuff
}
}
}
如果 do stuff
很长,它可以而且应该重构为一个单独的方法(可能包括内部 try-with-resources)。