在这种情况下,为什么不能使用try-with-resource?

时间:2013-06-20 21:04:59

标签: java resources try-catch

以下代码可以正常使用:

String connStr = "jdbc:mysql://localhost:3306/addressbook";

try ( Connection conn = DriverManager.getConnection(connStr, "root", "");
    PreparedStatement ps = conn.prepareStatement("select * from contact where firstName=?");
        ) {

    ps.setString(1, "Cippo");
    ResultSet rs = ps.executeQuery();

    while(rs.next()) {
        System.out.print(rs.getString(2) + "\t");
        System.out.print(rs.getString(3) + "\t");
        System.out.print(rs.getInt(1) + "\t");
        System.out.print(rs.getString(4) + "\t");
        System.out.println(rs.getString(5));                    
    }

} catch (SQLException e) {
    e.printStackTrace();
    System.exit(-1);
}

但是出于一个神秘的原因,当我将其他两个指令移动到try-with-resource块(它们应该保留在那里)时,我收到了一个编译错误:

String connStr = "jdbc:mysql://localhost:3306/addressbook";

try ( Connection conn = DriverManager.getConnection(connStr, "root", "");
    PreparedStatement ps = conn.prepareStatement("select * from contact where firstName=?");
        ps.setString(1, "Cippo");
        ResultSet rs = ps.executeQuery();
        ) { 

    while(rs.next()) {
        System.out.print(rs.getString(2) + "\t");
        System.out.print(rs.getString(3) + "\t");
        System.out.print(rs.getInt(1) + "\t");
        System.out.print(rs.getString(4) + "\t");
        System.out.println(rs.getString(5));                    
    }

} catch (SQLException e) {
    e.printStackTrace();
    System.exit(-1);
}

编译错误是不合理的:“ps无法解析”。但conn解决没有任何问题。为什么?

3 个答案:

答案 0 :(得分:0)

try with resources语法用于分配实现autocloseable的对象,例如流和数据库连接,以便在发生异常时可以正确清理它们。它不是为执行任意附加代码而设计的。

我没有真正看到你试图通过将这两个指令放在try语句的分配部分中来实现,因为你已经在第一个例子中获得了相同的结果。

更新:我想知道您是否将ResultSet置于试用版中,以便在失败时自动关闭。如果是这种情况,那么我认为它应该通过对语句对象的close调用自动关闭。如果您担心使用ResultSet的资源进行单独的内部尝试就足够了。

答案 1 :(得分:0)

这就是Java语法的定义方式:

来自Java Language Specification, Section 14.20.3 try-with-resources

  

try-with-resources语句使用变量进行参数化(已知)   在执行try块之前初始化的资源)   并按照与之相反的顺序自动关闭   执行try块后初始化。   [...]

     

ResourceSpecification 声明一个或多个局部变量   初始化表达式充当try语句的资源。

答案 2 :(得分:0)

在捕获任何内部异常之前,

AutoCloseable http://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html已关闭。因此,不可能将AutoCloeable放在try-resource块中,也不能放在try块中。