【问题标题】:Is it possible to stop execution of finally block?是否可以停止执行 finally 块?
【发布时间】:2015-03-29 19:05:23
【问题描述】:

这没有任何意义,我仍然很想知道是否可以在 java 中停止执行 finally 块?如果是,如何? 比如下面的代码:

public class Foo 
{  
    public static void main(String[] args) 
    {
        try 
        { 
            return; 
        } 
        finally 
        {
            System.out.println( "Yes, I executed successfully." ); 
        } 
    } 
}

我希望控制台上的输出不会像是的,我执行成功了。

嗯,这似乎是可能的,我得出结论。所有的答案都有一些东西 不同的是接受它是可能的。所以,我不接受任何 具体回答。根据您的满意程度,请他们得出结论。谢谢大家 谁发布了答案。

【问题讨论】:

    标签: java exception-handling finally


    【解决方案1】:
    1. A infinite loop above it will stop its execution
    2. System.exit() above it will stop it
    

    【讨论】:

    • 是的,你上面给出的情况完全不同,**上面的无限循环将停止执行**。太棒了..
    • 无限循环绝对不会停止finally 块的执行。该块只是无限期地继续执行。更重要的是,finally 之后的任何代码都不会被执行。
    【解决方案2】:

    我还没有遇到您实际需要的情况。但其典型的面试问题和答案是

       System.exit(0) 
    

    Difference in System. exit(0) , System.exit(-1), System.exit(1 ) in Java

    【讨论】:

      【解决方案3】:

      Thread.stop() 导致在目标线程中抛出异常。这是异步发生的,也可能在执行finally 块时发生。在这种情况下,finally 块将突然完成,但允许它发生的线程继续执行。

      try {
        try {
          ...code...
        } finally { 
           ...resource cleanup, ThreadDeath thrown here...
        }
      } catch (ThreadDeath t) {
        System.out.println("Thread was ordered to stop, ignoring.");
      }
      

      【讨论】:

      • 在这种情况下,如果我没记错,finally 块将执行!
      • 它将开始执行,但可能永远不会执行一条指令。具体来说,您的System.out.println() 可能永远不会执行。
      • 是的,我明白了.. 感谢您的澄清。
      【解决方案4】:

      来自JLS §14.20.2

      带有finally 块的try 语句首先执行 try 块。然后有一个选择:

      • 如果try块的执行正常完成,则finally块被执行,然后有一个选择:
        • 如果finally 块正常完成,则try 语句正常完成。
        • 如果finally 块由于原因S 而突然完成,那么try 语句由于原因S 而突然完成。
      • 如果try 块的执行由于抛出一个值V 而突然完成,那么有一个选择:
        • 如果V 的运行时类型是与try 语句的任何catch 子句的可捕获异常类兼容的赋值, 然后选择第一个(最左边)这样的catch 子句。值V 分配给所选catch 子句的参数,并且 该catch 子句的块被执行。然后有一个选择:
          • 如果catch 块正常完成,则执行finally 块。然后有一个选择:
            • 如果finally 块正常完成,则try 语句正常完成。
            • 如果 finally 块出于任何原因突然完成,那么 try 语句也会出于同样的原因而突然完成。
          • 如果catch 块由于R 原因突然完成,则执行finally 块。然后有一个选择:
            • 如果finally 块正常完成,则try 语句会因为R 而突然完成。
            • 如果finally 块由于原因S 而突然完成,那么try 语句由于原因S 而突然完成(并且原因R 是 丢弃)。
        • 如果V 的运行时类型与try 语句的任何catch 子句的可捕获异常类的赋值不兼容, 然后执行finally 块。然后有一个选择:
          • 如果finally 块正常完成,则try 语句会因为抛出V 值而突然完成。
          • 如果finally 块因为S 而突然完成,那么try 语句因为S 而突然完成(以及抛出值 V 被丢弃和遗忘)。
      • 如果try 块的执行由于任何其他原因突然完成R,则执行finally 块,然后有一个 选择:
        • 如果finally 块正常完成,则try 语句会因为R 而突然完成。
        • 如果finally 块由于原因S 而突然完成,那么try 语句由于原因S 而突然完成(并且原因R 是 丢弃)。

      简而言之,如果 JVM 没有退出(通过 System.exit),那么 finally 块将始终运行。

      但是finally块可能会异常退出,例如抛出异常,在这种情况下finally块只会被部分执行。

      【讨论】:

      • 它正在运行,但可能无法正常完成
      • 如果出现线程死亡的情况,那么最终会阻塞执行吗?
      • @choxx Thread.stop 抛出异常 - finally 仍会运行。 Thread.destroy - 实际上我不确定,但我认为 finally 不会运行。然而,这两种方法早已被弃用。
      • ThreadDeath 发生 within finally 将减少其执行并使其突然完成。这就是问题所在。
      • @MarkoTopolnik 但这并不是真正的 finally 块问题,而是这些方法被弃用的核心原因 - Threaddrops 所有监视器,然后......消失了。还不如destory 但是...
      【解决方案5】:

      我认为this 说得最好:

      注意:如果在执行 try 或 catch 代码时 JVM 退出,则 finally 块可能不会执行。同样,如果执行 try 或 catch 代码的线程被中断或杀死,即使应用程序作为一个整体继续运行,finally 块也可能不会执行。

      但是,try 中的 return 语句不会阻止 finally 块的执行。也不会抛出异常。这种行为是为什么 finally 块首先存在的原因。它可以让您可靠地清理资源。

      【讨论】:

      • 你的意思是说即使执行try或catch代码的线程被中断或杀死,应用程序仍有可能继续执行,并且finally块可能不会执行?
      • 在多线程应用程序中是的。尽管“机会”具有误导性。有些东西必须故意杀死线程。
      • 非常感谢您的回答,但如果可能的话,您能否给我一个链接或示例来展示我在上述评论中所说的情况?
      猜你喜欢
      • 2011-11-01
      • 2010-10-15
      • 2011-02-18
      • 2017-09-04
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      相关资源
      最近更新 更多