java:try finally阻止执行

java:try finally阻止执行,java,try-catch,finally,Java,Try Catch,Finally,当存在返回时,我对try finally执行感到困惑在try块中。在我的理解中,finally块将始终被执行,即在返回到调用方法之前。在考虑以下简单代码时: public class TryCatchTest { public static void main(String[] args){ System.out.println(test()); } static int test(){ int x = 1; try{

当存在
返回时,我对try finally执行感到困惑在try块中。在我的理解中,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块?有人能帮我吗?

当您从
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;
}
建议阅读:


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

根据Java语言规范:

带有表达式的return语句尝试将控制转移到调用程序 包含它的方法的名称;表达式的值将成为的值 方法调用

前面的描述说的是“试图转移控制权”,而不仅仅是“转移控制权” 控件”,因为如果方法或构造函数中存在任何try语句(§14.20) 其try块或catch子句包含return语句,然后是any finally 这些try语句的子句将在 控件被转移到方法或构造函数的调用方。突然完成一项任务 finally子句可以中断由return语句启动的控制权转移


在退出前返回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;
        }
    }
}

为什么不在finally块中添加一个
System.out.println()
,看看你自己呢?我认为它已经执行了,但返回的值是1。当使用try-catch时,您可以“捕获”特定类型的异常(例如:IOException、NullPointerException等)。finally语句在特定异常发生时出现,您需要在捕获之前运行一些代码。。。有什么可以考虑的吗upvoting@RicardoE-不完全正确。如果输入了try区域,finally子句(缺少一些混乱的递归异常情况)总是被执行。@Keyser因为Rohit这样的人会花时间解释发生了什么以及所有的底层功能,以便每个人,而不仅仅是询问者,可以进行更全面的理解。此外,只有返回值本身存储在堆栈上。如果返回对对象的引用,在
finally
块中对对象字段所做的修改仍然可见。@JasonC。没错。这将增加答案。谢谢:)如果有人不明白为什么
builder=null
不能使返回值为空,那是因为这个原因。@Keyser。是的,就是这样。我认为这没有抓住重点。嗯,我想有人必须真正阅读文档。每个派对都有一个扫兴的人。