尝试使用Java 1.6中的资源等效

时间:2014-05-12 14:37:29

标签: java try-catch try-with-resources

我有以下代码:

    public class Main {

        public static void main(String[] args) throws SQLException {

            try (
                    Connection conn = DBUtil.getConnection(DBType.HSQLDB);
                    Statement stmt = conn.createStatement(
                            ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
                    ResultSet rs = stmt.executeQuery("SELECT * FROM tours");
                    ) {

            DBUtil.getConnection();

            } catch (SQLException e) {
                DBUtil.processException(e);
            } 

        }

    }

我使用此代码从数据库中获取数据。我的问题是我不允许使用Java 1.7编译器并且必须使用1.6。 如何将try-with-resources-code转换为与1.6编译器一起使用? 在这个特殊的试块中究竟发生了什么?

3 个答案:

答案 0 :(得分:9)

Oracle解释了try-with-resources如何运作here

TL;它的DR是:
在Java 1.6中没有简单的方法。问题是Exception中没有Suppressed字段。您可以忽略它并硬编码当尝试AND关闭抛出不同异常时发生的事情,或者创建自己的具有被抑制字段的Exception子层次结构。

在第二种情况下,上面的链接提供了正确的方法:

   AutoClose autoClose = new AutoClose();
   MyException myException = null;
   try {
       autoClose.work();
   } catch (MyException e) {
       myException = e;
       throw e;
   } finally {
       if (myException != null) {
           try {
               autoClose.close();
           } catch (Throwable t) {
               myException.addSuppressed(t);
           }
       } else {
           autoClose.close();
       }
   }  

相当于

try (AutoClose autoClose = new AutoClose()) {
    autoClose.work();
}

如果你想让它变得更容易并且不创建大量新的Exception类,你将必须决定在finally(t或e)中的catch子句中抛出什么。

PS。在上面的链接中还讨论了在try中处理多个变量声明。而正确所需的代码量是惊人的。大多数人通过不处理finally块中的异常并使用nullcheck来获取Java 1.6中的快捷方式。

答案 1 :(得分:1)

这样做:

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
    conn = DBUtil.getConnection(DBType.HSQLDB);
    stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
    rs = stmt.executeQuery("SELECT * FROM tours");
} catch (SQLException e) {
    DBUtil.processException(e);
} finally {
    if(conn != null) {
        conn.close();
    }
    if(stmt != null) {
        stmt.close();
    }
    if(rs != null) {
        rs.close();
    }
}

答案 2 :(得分:1)

我建议使用apache的commons-dbutils库,其中DBUtils类包含closecloseQuietly方法。 代码如下所示:

import org.apache.commons.dbutils.DBUtils;
...
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
    conn = myOwnUtil.getConnection();
    stmt = conn.createStatement();
    rs = stmt.executeQuery( "SELECT * FROM table" ); // or any other custom query
} catch ( SQLException e ) {
    <<handle exception here>>;
} finally {
    DBUtils.closeQuietly( conn );
    DBUtils.closeQuietly( stmt );
    DBUtils.closeQuietly( rs );
    // or simply use DBUtils.close( conn, stmt, rs );
}

请注意,closeQuietly不会抛出任何异常,而close可能会抛出SQLException,因此请将代码调整为您自己的用例。

如果你想关闭流,你可以使用apache&#39; commons-io和IOUtils类,它们也有close和closeQuietly。