Java 即使抛出新异常,finally块也会运行吗?

Java 即使抛出新异常,finally块也会运行吗?,java,exception-handling,Java,Exception Handling,在此代码中,即使执行catch块并引发第二个异常,是否会设置someVar public void someFunction() throws Exception { try { //CODE HERE } catch (Exception e) { Log.e(TAG, "", e); throw new Exception(e); } finally { this.someVar= true; }

在此代码中,即使执行catch块并引发第二个异常,是否会设置
someVar

public void someFunction() throws Exception {
    try {
        //CODE HERE
    } catch (Exception e) {
        Log.e(TAG, "", e);
        throw new Exception(e);
    } finally {
        this.someVar= true;
    }
}

见:

finally块总是在 try块退出

例外情况:

注意:如果JVM在重试时退出 或者正在执行捕获代码,然后 finally块可能不执行。 同样,如果执行 try或catch代码被中断或丢失 杀了,最后挡不住 即使应用程序是 整个过程仍在继续


。除非您已在“尝试或捕获”中退出System.exit(0)。

finally
块始终执行,但调用System.exit()的情况除外,因为它会停止Java VM。

是的,finally块始终运行。。。除非:

  • 运行try-catch-finally块的线程被终止或中断
  • 您使用
    System.exit(0)
  • 底层VM以其他方式被破坏
  • 底层硬件在某种程度上无法使用
此外,如果finally块中的一个方法抛出一个未捕获的异常,那么之后将不会执行任何操作(即,异常将像在任何其他代码中一样被抛出)。发生这种情况的一种非常常见的情况是
java.sql.Connection.close()


顺便说一句,我猜您使用的代码示例只是一个示例,但请小心将实际逻辑放在finally块中。finally块用于资源清理(关闭数据库连接、释放文件句柄等),而不是用于必须运行的逻辑。如果它必须在try-catch块之前运行doit,远离可能引发异常的东西,因为您的意图几乎肯定在功能上是相同的。

无论您的情况是什么,最终总是执行

  • 试着抓住最后一块
  • 投掷
对于未检查的异常,java不强制执行错误处理。 这就是原因,如果finally块中发生未经检查的异常,并且没有对此进行任何处理,则在此点(发生错误的位置)下编写的代码将不会执行

因此,我建议始终处理所有异常,无论是否检查。
通过这种方式,您可以确保finally中的代码块也被执行,无论是否也发生未检查的异常。您在子嵌套捕获和最终块中有一个位置来完成必要的工作。

最后,块始终执行

public class ExceptionTest {

public static void someFunction(String input) throws Exception {
    try {
        if( input.equals("ABC") ) {
            System.out.println("Matched");
        }
    } catch (Exception e) {
        throw new Exception(e);
    } finally {
        System.out.println("Input Is "+input+" Finally Executed!!!");
    }
}

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    try {
        System.out.println("********* Test with VALUE ********* ");
        someFunction("ABC");
        System.out.println("\r\n********* Test with NULL  ********* ");
        someFunction(null);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}


因为有些情况下行为不符合预期,如@GaryFIt所示,值得注意的是,如果最后一个块抛出异常或返回,它可能不会按预期执行。在System.exit()之后仍会调用关闭挂钩,但现有的非系统线程都会停止。您这里所说的关闭挂钩是什么意思“运行try-catch-finally块的线程被[…]中断”?可能文档措词不当,但thread.interrupt()不会导致跳过finally块,无论是从try块还是catch块抛出。这是否使用“interrupted”来表示更猛烈的行为,如thread.stop()?@Joe:是的,我认为文档的措辞有点糟糕,它们意味着线程活动的全面中断。@GaryF-我认为您引用的是JLS。JLS的措辞有时有点奇怪,但您通常会发现奇怪术语的含义在文档的其他地方有明确的定义t、 JLS是一个规范,其主要目标是精确性(而不是可读性)。@Stephen C-事实上,这来自JavaSE教程(与其他人链接)。JLS中的措辞可能与之类似,但我找不到相关部分。我希望在第11章(例外)、第14章(声明)或第15章中可以看到这一点(表达式),但看不到任何明确提及中断的内容。我当然有兴趣看到它。@GaryF-我明白了。实际上JLS讨论了语句的“正常”和“突然”终止,并且有一节(14.1)这定义了术语。
最终
的行为将根据正常终止和突然终止来指定。