java Try-catch-finally 然后再次尝试捕获

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1335812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 16:09:55  来源:igfitidea点击:

Try-catch-finally and then again a try catch

javaexception-handlingtry-catch-finally

提问by Ajay

I have often come across situations like :-

我经常遇到这样的情况:-

try{ 
     ...
     stmts
     ...
} 
catch(Exception ex) {
     ... 
     stmts
     ... 
} finally {
     connection.close // throws an exception
}

which still needs a try - catch block inside finally.

最后仍然需要一个 try - catch 块。

What is the best practice to overcome this?

克服这个问题的最佳做法是什么?

采纳答案by Nick Holt

Write a SQLUtilsclass that contains static closeQuietlymethods that catch and log such exceptions, then use as appropriate.

编写一个SQLUtils包含static closeQuietly捕获和记录此类异常的方法的类,然后根据需要使用。

You'll end up with something that reads like this:

你最终会得到这样的东西:

public class SQLUtils 
{
  private static Log log = LogFactory.getLog(SQLUtils.class);

  public static void closeQuietly(Connection connection)
  {
    try
    {
      if (connection != null)
      {
        connection.close();
      }
    }
    catch (SQLExcetpion e)
    {
      log.error("An error occurred closing connection.", e);
    }
  }

  public static void closeQuietly(Statement statement)
  {
    try
    {
      if (statement!= null)
      {
        statement.close();
      }
    }
    catch (SQLExcetpion e)
    {
      log.error("An error occurred closing statement.", e);
    }
  }

  public static void closeQuietly(ResultSet resultSet)
  {
    try
    {
      if (resultSet!= null)
      {
        resultSet.close();
      }
    }
    catch (SQLExcetpion e)
    {
      log.error("An error occurred closing result set.", e);
    }
  }
}

And your client code will be something like:

您的客户端代码将类似于:

Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try 
{
  connection = getConnection();
  statement = connection.prepareStatement(...);
  resultSet = statement.executeQuery();

  ...
}
finally
{
  SQLUtils.closeQuietly(resultSet);
  SQLUtils.closeQuietly(statment);
  SQLUtils.closeQuietly(connection);
}

Update:since Java 7, the various JDBC interfaces extend java.lang.AutoCloseableand while the above code answers the original question, if you're writing code directly against the JDBC API, it can now be structured:

更新:从 Java 7 开始,各种 JDBC 接口得到扩展java.lang.AutoCloseable,虽然上面的代码回答了最初的问题,但如果您直接针对 JDBC API 编写代码,现在可以将其结构化:

try (
  Connection connection = getConnection();
  PreparedStatement statement = connection.prepareStatement(...);
  ResultSet resultSet = statement.executeQuery()
)
{
  ...
}

回答by serg10

As others have mentioned, a static closeQuietlyutility is the way to go. One thing to add - if you are in the world of java.iorather than java.sqlthen there is a useful interface for exactly this purpose - java.io.Closeable

正如其他人所提到的,静态closeQuietly实用程序是要走的路。要添加的一件事 - 如果您在世界中java.io而不是java.sql那么有一个用于此目的的有用界面 - java.io.Closeable

All the data sources and sinks in java.ioimplement this interface - all streams, channels, writers and readers. That way you can create a single utility to cope with the same "exception on close()" issue without requiring many overloaded versions.

所有数据源和接收器都java.io实现了这个接口——所有的流、通道、写入器和读取器。这样您就可以创建一个实用程序来处理相同的“close() 异常”问题,而无需许多重载版本。

e.g.

例如

public class IoUtils {

  public static closeQuietly (Closeable closeable) {
    try {
      closeable.close();
    } catch (IOException logAndContinue) {
      ...
    }
  }

}

回答by seth

I usually did it this way:

我通常是这样做的:

try {
    try {
        ..
        stmts
        ...
    }
    finally {
       connection.close():
    }
} catch (Exception ex) {
     ..
     stmts
     ..    
}

I usually only used this when I wasn't using a library that took care of this plumbing for me.

我通常只在我没有使用为我处理这个管道的图书馆时才使用它。

As Imagistpoints out, this isn't technically the same as the finally will run before the catch but I think it solves the problem you were trying to solve.

正如Imagist指出的那样,这在技术上与最终将在捕获之前运行不同,但我认为它解决了您试图解决的问题。

回答by Wilfred Springer

Commons-io also has closeQuietly() for in and output streams. I'm using it all the time. It makes your code much more readable.

Commons-io 还具有用于输入和输出流的 closeQuietly()。我一直在使用它。它使您的代码更具可读性。

回答by gepree

In Java 10 you can write:

在 Java 10 中,您可以编写:

public void java10() throws SQLException {
    try (var connection = Connections.openConnection();
         var callableStatement = connection.prepareCall("my_call");
         var resultSet = callableStatement.executeQuery()) {

        while (resultSet.next()) {
            var value = resultSet.getString(1);
            System.out.println(value);
        }
    }
}

In Java 7, 8 and 9 you can write:

在 Java 7、8 和 9 中,您可以编写:

public void java7() throws SQLException {
    try (Connection connection = Connections.openConnection();
         CallableStatement callableStatement = connection.prepareCall("my_call");
         ResultSet resultSet = callableStatement.executeQuery()) {

        while (resultSet.next()) {
            String value = resultSet.getString(1);
            System.out.println(value);
        }
    }
}

In Java 6 you need to write all these lines:

在 Java 6 中,您需要编写所有这些行:

public void java6() throws SQLException {
    Connection connection = Connections.openConnection();
    try {
        CallableStatement callableStatement = connection.prepareCall("my_call");
        try {
            ResultSet resultSet = callableStatement.executeQuery();
            try {
                while (resultSet.next()) {
                    String value = resultSet.getString(1);
                    System.out.println(value);
                }
            } finally {
                try {
                    resultSet.close();
                } catch (Exception ignored) {
                }
            }
        } finally {
            try {
                callableStatement.close();
            } catch (Exception ignored) {
            }
        }
    } finally {
        try {
            connection.close();
        } catch (Exception ignored) {
        }
    }
}

回答by Dewfy

Don't hesitate use one more try ... catch inside finally.

不要犹豫,再试一次……最后抓住里面。

回答by Yishai

Generally you don't want to do anything more than log an exception which happens when closing a resource, so it should really go in its own try/catch. However, this is generic code that will happen often, so Don't Repeat Yourself, and put the close in a static method (as Nick Holt suggests) that way you won't have the two try/catch items in the same method, making the code easier to read and follow.

通常,除了记录关闭资源时发生的异常之外,您不想做任何事情,因此它应该真正进入自己的 try/catch。但是,这是经常发生的通用代码,所以不要重复自己,并将关闭放在静态方法中(如尼克霍尔特建议的那样),这样您就不会在同一方法中使用两个 try/catch 项,使代码更易于阅读和遵循。

回答by chipiik

There is also handy Closeables#closeQuitely method in Google Guava library - it can be used for any Closeable

Google Guava 库中还有一个方便的 Closeables#closeQuitely 方法 - 它可以用于任何 Closeable

回答by Robert Langdon

Can we have try block followed by finally bock and catch block later to that?

我们可以先 try 块,然后是 finally bock 和 catch 块吗?

回答by rty

just remember .. finally always get execute either with try or catch ..

请记住 .. 最后总是使用 try 或 catch 来执行 ..