如何访问bock外的try-with-resource变量?

时间:2018-05-22 15:00:46

标签: java

为什么我不能在try块之外分配try-with-resource variable

以下声明无效:

Connection con = null;
try (con = DatabaseService.getConnection()) { //this is invalid. why?
     con.execute(...);
} catch (Exception e) {
    con.rollback();
}

如何访问con块中的catch变量?

5 个答案:

答案 0 :(得分:6)

这仅适用于Java版本8.自Java 9以来已经改进。

使用Java 9,通过引入新语法改进了Try-With-Resources:

public void loadDataFromDB() throws SQLException {
    Connection dbCon = DriverManager.getConnection("url", "user", "password");
    try (dbCon; ResultSet rs = dbCon.createStatement().executeQuery("select * from emp")) {
        while (rs.next()) {
            System.out.println("In method loadDataFromDB()" + rs.getString(1));
        }
    } catch (SQLException e) {
        System.out.println("Exception occured while reading data from DB " + e.getMessage());
    }
}

使用Java 8或更低版本编译时相同会导致编译错误。

在Java 9中,您可以使用try和catch块范围内的变量。

答案 1 :(得分:4)

我这样设计:

try (Connection con = DatabaseService.getConnection()) {
    try {
        con.execute(...);
    } catch (Exception e) {
        con.rollback();
    }
}

答案 2 :(得分:3)

由于try-with-resources在AutoCloseable类上调用close(),您可以返回手动关闭连接:

Connection con = DatabaseService.getConnection();
try {
    con.execute(...);
} catch (Exception e) {
    con.rollback();
} finally {
    con.close();
}

答案 3 :(得分:1)

我的回答是基于 @Luiggi Mendoza 的回答:

public void doWithConnection() throws SQLException {
    try (Connection con = DatabaseService.getConnection()) {
        execute(con);
    }
}

private void execute(Connection con) throws SQLException {
    try {
        // TODO do smth. here
    } catch(Exception e) {
        con.rollback();
    }
}

答案 4 :(得分:1)

实际上,从 Java 9 开始,您可以将 try-with-resources 与 final 或有效的 final 变量一起使用。因此,您可以在 try 块之外初始化该变量,并在 try-with-resources 块中指明您要使用它。这样,变量在 catch 块的作用域内是可用的。

Connection con = DatabaseService.getConnection();
try (con) {
     con.execute(...);
} catch (Exception e) {
    con.rollback();
}

注意:即使变量在 catch 方法中可用,对 close() 方法的调用也会在它进入 catch 或 finally 块之前发生。因此,在这种情况下,在事务中调用 rollback() 没有用处,但可以从对象状态中收集其他信息。