【问题标题】:What's the difference between code inside finally block and code after finally block?finally 块中的代码和 finally 块之后的代码有什么区别?
【发布时间】:2014-05-28 19:06:40
【问题描述】:

我想知道 finally 块中的代码和 finally 块之后的代码有什么区别

【问题讨论】:

  • ....finally 块之后的代码在finally 块中的代码之后执行?
  • @Kick Buttowski 你为什么这么认为?这对我来说很有意义。这是一个很容易理解的问题。

标签: java try-catch try-catch-finally finally


【解决方案1】:

一个小测试程序显示了差异:

public class FinallyTest {

    public static void main(String[] args) throws Exception {
        try {
            boolean flag = true;
            if (flag) {
                throw new Exception("hello");
            }
        } finally {
            System.out.println("this will get printed");
        }
        System.out.println("this won't show up");
    }
}

程序抛出异常,执行程序的JVM捕获并打印出来。

写入控制台的内容是:

this will get printed
Exception in thread "main" java.lang.Exception: hello
    at snippet.FinallyTest.main(FinallyTest.java:7)

一旦抛出异常,该线程将执行的唯一事情(直到异常被 JVM 捕获)是 finally 块(异常离开 finally 所属的 try 块)。

【讨论】:

  • 谢谢。一位同事试图告诉我,只要有一个 finally 块,那么 finally 块之后的代码将由于某种原因与 finally 块中的代码相同地执行。回想起来答案是显而易见的,但这个答案让事情变得很清楚。
【解决方案2】:

如果 catch 块重新抛出异常(或抛出新异常),则执行 finally 块。 finally 块之后的任何内容都不会被执行。

finally 块总是在 try 块退出时执行。这可以确保即使发生意外异常也会执行 finally 块。但是 finally 不仅仅对异常处理有用——它允许程序员避免清理代码被 return、continue 或 break 意外绕过。将清理代码放在 finally 块中始终是一个好习惯,即使没有预料到异常也是如此。 - http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html

【讨论】:

    【解决方案3】:

    如果你在 catch 块上抛出异常,或者如果你在 try 块上返回一些东西,它将执行 finally 块。如果不在 finally 块上(在 try/catch/finally 之后),它将无法工作。这里有一个简单的例子供你理解:在没有 finally 块的情况下尝试它,你会看到它打印消息“正在关闭资源...”的行将永远不会被执行。

    try {
        return "Something";
    } catch (Exception e) {
        throw e;
    } finally {
        System.out.println("Closing resources (Connections, etc.)...");//This will always execute
    }
    

    【讨论】:

    • 只有一种情况,finally 块不会被执行,就是我们在 try 块中使用 System.exit(0) 方法时。
    【解决方案4】:

    在这里,我在上面提供的示例中添加了更多内容,可能会在将来对某人有所帮助,并希望避免一些混乱。

    让我们开始吧。

    其实还是要看程序的流控。这意味着如果程序的编写方式是,如果您的代码正在处理 try 块中抛出的异常,并且如果您在 catch 块中处理它们,那么 finally 块之后的代码将在 finally 块中的代码之后执行块。

    示例1:这里的异常已经被处理,因此finally之后的代码,块执行。

    public class TestFinally {
    
        public static void main(String[] args) throws Exception {
            try {
                boolean flag = true;
                if (flag) {
                    throw new Exception("hello");
                }
            } 
            catch(Exception e){
                System.out.println("catch will get printed");   
            }
            finally {
                System.out.println("this will get printed");
            }
            System.out.println("this won't show up");
        }
    }
    

    结果:

    catch will get printed
    this will get printed
    this won't show up
    

    示例 2: 如果 try 块中的异常没有按照上面 Nathan 的说明正确处理,则 finally 块之后的代码不会被执行。

    public class TestFinally {
    
        public static void main(String[] args) throws Exception {
            try {
                boolean flag = true;
                if (flag) {
                    throw new Exception("hello");
                }
            } 
            // not handling the exception thrown above
            /*catch(Exception e){
                System.out.println("catch will get printed");   
            }*/
            finally {
                System.out.println("this will get printed");
            }
            System.out.println("this won't show up");
        }
    }
    

    结果:

    this will get printed
    Exception in thread "main" java.lang.Exception: hello
        at com.test.TestFinally.main(TestFinally.java:36)
    

    因此,总而言之,finally 块内的代码总是会执行,除非在某些情况下线程在 finally 块之前已停止或终止,或者以防在 try 块中写入任何退出程序。而 finally 之后的代码依赖于 try-catch-finally 块中编写的代码以及异常处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-09
      • 2014-08-27
      • 2013-01-12
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 2019-03-17
      相关资源
      最近更新 更多