考虑到这段代码,我能绝对确定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");
}

当前回答

在正常的执行过程中考虑这一点(即不抛出任何异常):如果方法不是“void”,那么它总是显式返回一些东西,然而,最终总是执行

其他回答

尝试这段代码,您将了解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;
    }
}

是的,finally将在执行try或catch代码块后调用。

唯一不会被调用的时间是:

如果调用System.exit()如果调用Runtime.getRuntime().hart(exitStatus)如果JVM首先崩溃如果JVM到达try或catch块中的无限循环(或其他一些不可中断、不终止的语句)如果操作系统强制终止JVM进程;例如,在UNIX上,kill-9<pid>如果主机系统失效;例如,电源故障、硬件错误、操作系统死机等如果finally块将由守护程序线程执行,并且所有其他非守护程序线程在finally调用之前退出

在两种独特的情况下,返回后不会调用finally块:如果首先调用System.exit(),或者JVM崩溃。

让我尽量用最简单的方式回答你的问题。

规则1:finally块始终运行(虽然有例外。但让我们坚持一段时间。)

规则2:当控件离开try或catch块时,finally块中的语句会运行。控制权的转移可能是正常执行、break、continue、goto或return语句的执行或异常传播的结果。

在返回语句的情况下(由于其标题),控件必须离开调用方法,因此调用相应try finally结构的finally块。return语句在finally块之后执行。

如果finally块中也有return语句,它肯定会覆盖try块中挂起的语句,因为它会清除调用堆栈。

您可以在此处找到更好的解释:http://msdn.microsoft.com/en-us/....这一概念在所有高级语言中基本相同。

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

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

是的,因为没有控制语句可以阻止finally被执行。

下面是一个参考示例,其中将执行所有代码块:

| x | Current result | Code 
|---|----------------|------ - - -
|   |                |     
|   |                | public static int finallyTest() {
| 3 |                |     int x = 3;
|   |                |     try {
|   |                |        try {
| 4 |                |             x++;
| 4 | return 4       |             return x;
|   |                |         } finally {
| 3 |                |             x--;
| 3 | throw          |             throw new RuntimeException("Ahh!");
|   |                |         }
|   |                |     } catch (RuntimeException e) {
| 4 | return 4       |         return ++x;
|   |                |     } finally {
| 3 |                |         x--;
|   |                |     }
|   |                | }
|   |                |
|---|----------------|------ - - -
|   | Result: 4      |

在下面的变体中,返回x;将跳过。结果仍然是4:

public static int finallyTest() {
    int x = 3;
    try {
        try {
            x++;
            if (true) throw new RuntimeException("Ahh!");
            return x; // skipped
        } finally {
            x--;
        }
    } catch (RuntimeException e) {
        return ++x;
    } finally {
        x--;
    }
}

当然,引用可以跟踪其状态。此示例返回值为4的引用:

static class IntRef { public int value; }
public static IntRef finallyTest() {
    IntRef x = new IntRef();
    x.value = 3;
    try {
        return x;
    } finally {
        x.value++; // will be tracked even after return
    }
}