【问题标题】:Does it make sense to do "try-finally" without "catch"?在没有“catch”的情况下做“try-finally”有意义吗?
【发布时间】:2011-02-06 13:17:00
【问题描述】:

我看到了一些这样的代码:

    try
    {
        db.store(mydata);
    }
    finally
    {
        db.cleanup();
    }

我认为try 应该有一个catch

为什么这段代码会这样?

【问题讨论】:

  • 它确保像提到的其他响应一样清理,特别是对于文件句柄fopen 或数据库连接(也在 PHP 中)

标签: java exception


【解决方案1】:

如果您希望当前执行的方法仍然抛出异常,同时允许适当地清理资源,这很有用。下面是一个处理调用方法异常的具体示例。

public void yourOtherMethod() {
    try {
        yourMethod();
    } catch (YourException ex) {
        // handle exception
    }
}    

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}

【讨论】:

  • 常用于锁如:lock.lock();尝试 { /* 锁定 */ } 最后 { lock.unlock() }
  • 如果finally里面抛出异常会怎样?
  • @barth 当没有catch 块时,finally 中抛出的异常将在try 块中的任何异常之前执行。因此,如果有两个异常,一个在 try 中,一个在 finally 中,唯一会抛出的异常是 finally 中的一个。这种行为在 PHP 和 Python 中是不同的,因为在这些语言中会同时抛出两个异常,并且异常顺序是 try 先是 finally
【解决方案2】:

它存在是因为程序员想要确保调用 db.cleanup(),即使 try 块内的代码抛出异常也是如此。该块不会处理任何异常,但它们只会在 finally 块执行后向上传播。如果没有异常,finally块也会被执行。

【讨论】:

  • +1 没错。 try 只是为了允许finally。异常不会被捕获。
【解决方案3】:

为什么这段代码会这样?

因为显然代码不知道如何处理这个级别的异常。 没关系——只要调用者之一这样做,即只要异常最终在某个地方得到处理。

通常,低级代码无法对异常做出适当的反应,因为需要通知用户,或者必须记录异常,或者必须尝试其他策略。低级代码只执行一个功能,不知道更高级别的决策。

但是代码仍然需要清理它的资源(因为如果不清理,它们就会泄漏),所以它只是在 finally 子句中这样做,确保它始终发生,无论是否引发异常。

【讨论】:

    【解决方案4】:

    finally 块确保即使抛出 RuntimeException(可能是由于被调用代码中的某些错误),也会进行 db.cleanup() 调用。

    这也常用于防止嵌套过多:

    try
    {
        if (foo) return false;
        //bla ...
        return true;
    }
    finally
    {
        //clean up
    }
    

    特别是当方法返回的点很多时,这会提高可读性,因为任何人都可以看到在每种情况下都会调用清理代码。

    【讨论】:

      【解决方案5】:

      代码这样做是为了确保数据库已关闭。
      通常,您的做法是将所有数据库访问代码放在 try 块中,然后在 finally 块中调用关闭数据库。
      try...finally 的工作方式,意味着 try 块中的代码运行,并且 finally 块中的代码在结束时运行...无论如何。
      如果计算机没有被从墙上拉下来,finally 就会执行。
      这意味着即使调用了异常,并且该方法执行需要三年时间,它仍然会进入 finally 块并关闭数据库。

      【讨论】:

        【解决方案6】:

        如果 try 块中的任何代码可以抛出已检查异常,则它必须出现在方法签名的 throws 子句中。如果抛出未经检查的异常,它就会从方法中冒泡出来。

        finally 块总是被执行,无论是否抛出异常。

        【讨论】:

          猜你喜欢
          • 2011-06-01
          • 2014-12-09
          • 2011-05-17
          • 1970-01-01
          • 2016-08-18
          • 2011-08-25
          • 1970-01-01
          • 2014-11-27
          • 1970-01-01
          相关资源
          最近更新 更多