考虑到这段代码,我能绝对确定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 is always run这就是重点,只是因为它出现在返回后的代码中并不意味着它就是这样实现的。Java运行时有责任在退出try块时运行此代码。

例如,如果您有以下内容:

int foo() { 
    try {
        return 42;
    }
    finally {
        System.out.println("done");
    }
}

运行时将生成如下内容:

int foo() {
    int ret = 42;
    System.out.println("done");
    return 42;
}

如果抛出未捕获的异常,finally块将运行,异常将继续传播。

其他回答

这是因为您将i的值指定为12,但没有将i的返回给函数。正确的代码如下:

public static int test() {
    int i = 0;
    try {
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
        return i;
    }
}

考虑以下程序:

public class SomeTest {

    private static StringBuilder sb = new StringBuilder();

    public static void main(String args[]) {

        System.out.println(someString());
        System.out.println("---AGAIN---");
        System.out.println(someString());
        System.out.println("---PRINT THE RESULT---");
        System.out.println(sb.toString());
    }

    private static String someString() {

        try {
            sb.append("-abc-");
            return sb.toString();

        } finally {
            sb.append("xyz");
        }
    }
}

从Java 1.8.162开始,上述代码块提供以下输出:

-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz

这意味着使用finally释放对象是一种很好的做法,如以下代码所示:

private static String someString() {

    StringBuilder sb = new StringBuilder();

    try {
        sb.append("abc");
        return sb.toString();

    } finally {
        sb = null; // Just an example, but you can close streams or DB connections this way.
    }
}

最终将执行,这是肯定的。

在以下情况下,finally将不执行:

案例1:

执行System.exit()时。

案例2:

当JVM/线程崩溃时。

案例3:

手动停止执行时。

我尝试了上面的示例,但稍作修改-

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

public static int test() {
    int i = 0;
    try {
        i = 2;
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
    }
}

上述代码输出:

最终战胜了回报。2.

这是因为当返回i;i的值为2。在此之后,执行finally块,其中12被分配给i,然后执行System.out-out。

在执行finally块之后,try块返回2,而不是返回12,因为该返回语句不会再次执行。

如果您将在Eclipse中调试此代码,那么您会感觉到在执行System.out of finally块之后,try块的返回语句将再次执行。但事实并非如此。它只返回值2。

除非由于JVM崩溃或调用System.exit(0)而导致程序异常终止,否则finally块将始终执行。

除此之外,finally块中返回的任何值都将覆盖finally块执行之前返回的值,因此在使用try finally时,请注意检查所有退出点。