【问题标题】:Does try/finally ignore exceptions?尝试/最终忽略异常吗?
【发布时间】:2023-03-30 09:13:01
【问题描述】:

我有一种情况,我希望无论发生什么都执行某些代码,但我还需要将异常传递到堆栈上以便稍后处理。如下:


try
{
  // code
}
finally
{
  // code that must run
}

只是忽略任何异常,还是将它们传递出去?我的测试似乎表明它们仍然可以通过,但我想确定我没有疯。

编辑:我的问题不是关于 finally 何时以及是否会执行,而是关于异常是否仍会向上抛出,但现在已经回答了。

【问题讨论】:

标签: exception exception-handling finally


【解决方案1】:

finally 代码将始终运行,并且如您所说,异常将向上传递。这几乎就是try/finally 的重点——让一些代码始终运行,即使抛出异常也是如此。

编辑:这适用于任何提供try/finally 构造的语言,但对于某些语言有一些注意事项,正如 Adam 在他的评论中指出的,Sam 在他的回答中指出的那样。

【讨论】:

  • 这不是真的,请参阅相关答案
  • 我相信里奇是对的;在 try/finally 中,try 块内的代码被执行,无论是否抛出异常,finally 块内的代码都会在之后执行。
  • @snake,查看我的答案和相关答案,在某些极端情况下,C# 中的 finally 不会被执行。
  • 你在回答什么,C# Java 还是 Javascript?
  • 在某些极端情况下,finally 块无法运行(一些 语言中的 StackOverflowException、进程终止、电源线被拉断等),但在大多数情况下在 finally 块将运行然后向下传播异常的情况下。
【解决方案2】:

这是一个测试类,显示(1)最终运行,无论是否抛出异常; (2) 异常被传递给调用者。

public class FinallyTest extends TestCase {
    private boolean finallyWasRun   = false;

    public void testFinallyRunsInNormalCase() throws Exception {
        assertFalse(finallyWasRun);
        f(false);
        assertTrue(finallyWasRun);
    }

    public void testFinallyRunsAndForwardsException() throws Exception {
        assertFalse(finallyWasRun);
        try {
            f(true);
            fail("expected an exception");
        } catch (Exception e) {
            assertTrue(finallyWasRun);
        }
    }

    private void f(boolean withException) throws Exception {
        try {
            if (withException)
                throw new Exception("");
        } finally {
            finallyWasRun = true;
        }
    }
}

【讨论】:

    【解决方案3】:

    假设这是 C#,finally 将一直运行,除非你得到 StackOverflowExceptionExecutingEngineException

    此外,像 ThreadAbortException 这样的异步异常可能会中断 finally 块的流程,导致它部分执行。

    查看相关问题:

    In C# will the Finally block be executed in a try, catch, finally if an unhandled exception is thrown?

    【讨论】:

      【解决方案4】:

      如果这是 C#

      这里的答案是正确的,finally 运行并且异常被“传递”。但是为了说明弄清楚它是多么容易:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      
      class Program
      {
          static void Main(string[] args)
          {
              try
              {
                  throw new Exception("testing");
              }
              finally
              {
                  Console.WriteLine("Finally");
              }
          }
      }
      

      当运行这个简单的小控制台应用程序时,会抛出异常,然后执行 finally 块。

      【讨论】:

        猜你喜欢
        • 2023-03-22
        • 1970-01-01
        • 2015-04-14
        • 2014-02-12
        • 2019-12-28
        • 1970-01-01
        • 2020-09-20
        • 2011-03-13
        相关资源
        最近更新 更多