【问题标题】:Will the finally block to be reached if there is "Where (true)" block in try block?如果try块中有“Where(true)”块,是否会到达finally块?
【发布时间】:2015-10-22 10:25:49
【问题描述】:

这是让我困惑的代码:

public Integer getInteger(BlockingQueue<Integer> queue) {
    boolean interrupted = false;
    try {
        while (true) {
            try {
                return queue.take();
            } catch (InterruptedException e) {
                interrupted = true;
                // fall through and retry
            }
        }
    } finally {
        if (interrupted)
            Thread.currentThread().interrupt();
    }
}

似乎 try 块不会因为 While(true) 块而停止,但有人告诉我 finally 块将始终在 try 块结束后执行。那么finally块什么时候执行呢?

【问题讨论】:

  • 如果try 块中确实存在无限循环,我认为你不会到达finally 块。

标签: java try-catch-finally


【解决方案1】:

当有另一个不是从 InterruptedException 派生的异常时

【讨论】:

  • 你的回答是正确的,但我觉得他应该重新设计他的逻辑,以不依赖于程序推进的异常。
  • 或者当无异常queue.take()导致返回时。
【解决方案2】:

finally 块将在 try 块完成时执行,在您的情况下可能有两个原因:

  • queue.take() 正常完成,也就是说它返回了一个值,这使得return 语句正常完成,并从带有来自take() 的值的方法返回。
  • queue.take() 通过抛出 Exception(或 Error)而不是 InterruptedException 突然完成。

Java 语言规范“Execution of try-finally and try-catch-finally”的缩写:

  • 如果try块的执行正常完成,那么finally块被执行 [...]

  • 如果 try 块的执行突然完成因为抛出了一个值 V,那么有一个选择:

    • 如果 V 的运行时类型与任何 catch 子句的可捕获异常类的赋值兼容 [...] 那么有一个选择:

      • 如果catch块正常完成,则finally块被执行 [...]

      • 如果 catch 块由于原因 R 突然完成,则 finally 块被执行 [...]

    • 如果 V 的运行时类型与 try 语句的任何 catch 子句的可捕获异常类的赋值不兼容,则执行 finally 块 [...]

  • 如果 try 块的执行由于任何其他原因 R 突然完成,则 finally 块被执行 [...]

所有路径都导致“最终块被执行”。

简而言之,finally总是try 块完成时执行,无论出于何种原因。避免这种情况发生的唯一方法是 JVM 异常终止(例如 JVM 终止、JVM 崩溃、操作系统崩溃或断电)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 2012-03-06
    • 2013-07-08
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    相关资源
    最近更新 更多