java:尝试finally块执行

时间:2013-08-08 16:39:19

标签: java try-catch finally

当try块中存在return;时,我对try-finally执行感到困惑。根据我的理解,finally块将始终执行,即在返回调用方法之前。在考虑以下简单代码时:

public class TryCatchTest {
    public static void main(String[] args){
        System.out.println(test());
    }
    static int test(){
        int x = 1;
        try{
            return x;
        }
        finally{
            x = x + 1;
        }
    }
}

打印的结果实际为1.这是否意味着finally块未执行?任何人都可以帮我吗?

3 个答案:

答案 0 :(得分:27)

try块返回时,返回值存储在该方法的堆栈帧中。之后执行finally块。

更改finally块中的值不会更改堆栈上已有的值。但是,如果再次从finally块返回,则将覆盖堆栈上的返回值,并返回新的x

如果您在finally块中打印x的值,您将知道它已被执行,并且x的值将被打印。

static int test(){
    int x = 1;
    try{
        return x;
    }
    finally{
        x = x + 1;
        System.out.println(x);  // Prints new value of x
    }
}

注意:如果返回引用值,则引用值将存储在堆栈中。在这种情况下,您可以使用该引用更改object的值。

StringBuilder builder = new StringBuilder("");
try {
    builder.append("Rohit ");
    return builder;

} finally {
    // Here you are changing the object pointed to by the reference
    builder.append("Jain");  // Return value will be `Rohit Jain`

    // However this will not nullify the return value. 
    // The value returned will still be `Rohit Jain`
    builder =  null;
}

建议阅读:

答案 1 :(得分:11)

执行finally块。局部变量递增。但是已经为返回值复制了该局部变量的值。

来自Java语言规范,14.17: The return statement

  

带有Expression的return语句尝试将控制权转移给调用者   包含它的方法;表达式的值变为值   方法调用。

     

...

     

前面的描述说“试图转移控制”而不仅仅是“转移”   控制“因为如果方法或构造函数中有任何try语句(§14.20)   其try块或catch子句包含return语句,然后是finally语句   这些try语句的子句将按顺序在最里面到最外面执行   控制权转移给方法或构造函数的调用者。突然完成一个   finally子句可以破坏由return语句启动的控制转移

答案 2 :(得分:0)

退出试用前,您将返回x。我会这样做:

public class TryCatchTest {
    public static void main(String[] args) {
        System.out.println(test());
    }
    static int test() {
        int x = 1;
        try {
            do something with x.
        } finally {
            do something that will happen even in case of error;
            x = x + 1;
            return x;
        }
    }
}