考虑到这段代码,我能绝对确定finally块总是执行的吗,不管something()是什么?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}

当前回答

尝试这段代码,您将了解finally块中的代码是在return语句之后执行的。

public class TestTryCatchFinally {
    static int x = 0;

    public static void main(String[] args){
        System.out.println(f1() );
        System.out.println(f2() );
    }

    public static int f1(){
        try{
            x = 1;
            return x;
        }finally{
            x = 2;
        }
    }

    public static int f2(){
        return x;
    }
}

其他回答

我对不同论坛上提供的所有答案感到非常困惑,最终决定编码并查看。输出为:

即使try-and-catch块中有返回,也将执行finally。

try {  
  System.out.println("try"); 
  return;
  //int  i =5/0;
  //System.exit(0 ) ;
} catch (Exception e) {   
  System.out.println("catch");
  return;
  //int  i =5/0;
  //System.exit(0 ) ;
} finally {  
   System.out.println("Print me FINALLY");
}

输出

尝试最后打印我

如果返回被上述代码中try-and-catch块中的System.exit(0)替换,并且由于任何原因,在它之前发生了异常。

是的,会的。唯一不会发生的情况是JVM退出或崩溃

添加到@vibhash的答案中,因为没有其他答案解释了在像下面这样的可变对象的情况下会发生什么。

public static void main(String[] args) {
    System.out.println(test().toString());
}

public static StringBuffer test() {
    StringBuffer s = new StringBuffer();
    try {
        s.append("sb");
        return s;
    } finally {
        s.append("updated ");
    }
}

将输出

sb已更新

如果不处理异常,在终止程序之前,JVM将执行finally块。仅当程序的正常执行因以下原因而失败时,才会执行程序。。

通过导致导致进程中止的致命错误。由于内存损坏,程序终止。通过调用System.exit()如果程序进入无限循环。

以下是一些可以绕过finally块的条件:

如果在执行try或catch代码时JVM退出,那么finally块可能不会执行。更多太阳教程正常关闭-当最后一个非守护程序线程退出时,或者当Runtime.exit()(一些不错的博客)时,都会发生这种情况。当线程退出时,JVM会对正在运行的线程进行盘点,如果只剩下守护进程线程,则会启动有序关闭。当JVM停止时,所有剩余的守护程序线程都将被放弃。如果不执行块,堆栈也不会被解开,JVM只会退出。守护程序线程应该很少使用,很少有处理活动可以在任何时候安全地放弃,而无需清理。特别是,将守护程序线程用于可能执行任何类型I/O的任务是危险的。守护程序线程最好保存用于“内务管理”任务,例如后台线程,它定期从内存缓存中删除过期条目(源)

最后一个非守护程序线程退出示例:

public class TestDaemon {
    private static Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                while (true) {
                    System.out.println("Is alive");
                    Thread.sleep(10);
                    // throw new RuntimeException();
                }
            } catch (Throwable t) {
                t.printStackTrace();
            } finally {
                System.out.println("This will never be executed.");
            }
        }
    };

    public static void main(String[] args) throws InterruptedException {
        Thread daemon = new Thread(runnable);
        daemon.setDaemon(true);
        daemon.start();
        Thread.sleep(100);
        // daemon.stop();
        System.out.println("Last non-daemon thread exits.");
    }
}

输出:

Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive