简体   繁体   English

等效于 Java 1.6 中的 Try-with-resources

[英]Try-with-resources equivalent in Java 1.6

I have the following code:我有以下代码:

    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);
            } 

        }

    }

I use this code to fetch data from a database.我使用此代码从数据库中获取数据。 My problem is that I'm not allowed to use the Java 1.7 compiler and have to use 1.6.我的问题是我不允许使用 Java 1.7 编译器而必须使用 1.6。 How can I translate the try-with-resources-code to use with a 1.6 compiler?如何翻译 try-with-resources-code 以与 1.6 编译器一起使用? What exactly happens in this special try block?在这个特殊的 try 块中到底发生了什么?

Oracle explains how try-with-resources works here Oracle 在这里解释了 try-with-resources 的工作原理

The TL;DR of it is:它的 TL; DR 是:
There is no simple way of doing this in Java 1.6.在 Java 1.6 中没有简单的方法可以做到这一点。 The problem is the absence of the Suppressed field in Exception.问题是异常中缺少 Suppressed 字段。 You can either ignore that and hardcode what happens when both try AND close throw different exceptions, or create your own Exception sub-hierarchy that has the suppressed field.您可以忽略它并硬编码当 try 和 close 都抛出不同的异常时会发生什么,或者创建自己的具有抑制字段的异常子层次结构。

In the second case, the link above gives the proper way of doing it:在第二种情况下,上面的链接给出了正确的方法:

   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();
       }
   }  

is equivalent to相当于

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

In case you want to make it easier and not create a whole lot of new Exception classes, you will have to decide what to throw in the catch clause inside the finally (t or e).如果您想让它更容易并且不想创建大量新的异常类,您将必须决定在 finally(t 或 e)中的 catch 子句中抛出什么。

PS.附注。 Dealing with multiple variable declaration in the try is also discussed in the link above.在上面的链接中也讨论了在 try 中处理多个变量声明。 And the amount of code that you need to do it properly is staggering.您需要正确执行的代码量是惊人的。 Most people take shortcuts in Java 1.6 by not coping with exceptions in the finally block and using nullchecks.大多数人在 Java 1.6 中通过不处理 finally 块中的异常并使用空检查来走捷径。

Do it like this:像这样做:

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();
    }
}

I would advise usage of apache's commons-dbutils library which have class DBUtils with close and closeQuietly methods.我会建议阿帕奇的使用公地dbutils库,它具有类DBUtilsclosecloseQuietly方法。 The code would look like this:代码如下所示:

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 );
}

Note that closeQuietly will throw no exceptions, while close might cast SQLException, so adapt the code to your own use case.请注意,closeQuietly 不会抛出任何异常,而 close 可能会抛出 SQLException,因此请根据您自己的用例调整代码。

If you want to close streams than you can use apache's commons-io with IOUtils class which also have close and closeQuietly.如果你想关闭流,那么你可以使用 apache 的commons-io和 IOUtils 类,它也有 close 和 closeQuietly。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM