没有内部catch块的嵌套try/catch

3

我想在内部try中嵌套一个try catch,而不需要在内部try中添加catch。
例如:

try (Connection conn = new Connection()) {
    //Fill preparedStatement etc
    try (ResultSet rs = conn.execute()){
    }
} catch (SQLException e) {
    //Log both exceptions here
}

这是否可行并且是否是一个好的实践方法?

2
为什么不直接将语句放在try块中,如果有任何异常被抛出,它将被外部catch块捕获。 - undefined
@Smit 这是一个简化版本。我需要先处理一些连接方面的事情。而且它并不像你说的那样关闭连接。 - undefined
嗨 @Luud van Keulen,我猜这是在Java7中引入的新方法。使用资源关闭语句期间避免异常非常有用,以免在运行时覆盖真实异常。所以你只能将此try用于分配任何资源语句,而不能用于实际实现。 - undefined
你尝试过这个的时候发生了什么? - undefined
看起来好像可以工作。不过我不知道如何引发一个 ResultSet 异常,所以也不确定它是否能正确捕获异常。 - undefined
2个回答

1
你可以这样做:

try (Connection conn = new Connection()) {
    ResultSet rs = conn.execute()
    // do stuff with rs
} catch (SQLException e) {
    // handle exception
}

conn.execute()抛出的异常将被catch块捕获。new Connection()抛出的异常将被抑制:

与try-with-resources语句相关联的代码块可能会引发异常。在writeToFileZipFileContents示例中,try块可能会引发异常,并且在尝试关闭ZipFile和BufferedWriter对象时,try-with-resources语句可能会引发最多两个异常。如果从try块引发异常并且从try-with-resources语句引发一个或多个异常,则来自try-with-resources语句的那些异常将被抑制,并且由writeToFileZipFileContents方法抛出的块引发的异常是被抛出的异常。您可以通过调用Throwable.getSuppressed方法从try块引发的异常中检索这些抑制的异常。

参见: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

编辑:正如Timothy指出的,Connection不能保证关闭其创建的ResultSet。因此,我们需要像这样:

try (Connection conn = new Connection(); 
     Statement statement = connection.createStatement()) {

    // statement.set(....)

    try (ResultSet rs = conn.execute()) {
        // do stuff with rs
    }

} catch (SQLException e) {
    // handle exceptions
}

啊,你说得对,Connection并不保证关闭它创建的ResultSet。 - undefined
@LuudvanKeulen 关闭ResultSet正是通过Connection.close()来实现的,通过Statement.close()进行承诺。这段代码唯一(微小)的问题是它本可以将ResultSet包含在需要关闭的资源中,而不是在try块内单独分配它。 - undefined
@LuudvanKeulen 是的,使用 try-with-resources 而没有 catch/finally 块是完全正常的。 - undefined
@AdriaanKoster Connection.close() 承诺关闭“所有 JDBC 资源”。请参阅 API。 - undefined
@EJP,我在任何地方都没有看到“all”这个词。在Java 7 API中,它说:“立即释放此Connection对象的数据库和JDBC资源”。所以问题是底层的结果集是否被认为属于Connection实例。相比之下,Statement的API有同样的句子,但还有以下内容:“注意:当关闭Statement对象时,如果存在当前的ResultSet对象,则也会关闭它。”这让我认为Statement明确保证了这一点,但Connection并没有那么明确。 - undefined
显示剩余4条评论

0

是的,但更好的是

try (Connection conn = new Connection(); ResultSet rs = conn.execute();){
    } catch (SQLException e) {
    //Log both exceptions here
}

这是一个简化版本。我首先需要创建PreparedStatement并填充参数。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接