关于一道finally的题

187 阅读2分钟

关于一道finally的题

如下,运行这个程序后,打印出的结果是怎样的?

public class FinallyTest {
    public static void main(String[] args){
        int result = m();
        System.out.println(result);
    }

    public static int m(){
        int i = 100;
        try {
            return i;
        }finally {
            i++;
        }
    }
}

众所周知,Java 中的 Finally 关键一般与try一起使用,在程序进入try块之后,无论程序是因为异常而中止或其它方式返回终止的,finally块的内容一定会被执行 。使用 finally 可以维护对象的内部状态,并可以清理非内存资源。

按初学的思想看,i=100,然后当要return i时,先执行finally语句块,i变成101,再return,sout出来是101,而结果显示的是100。为什么呢?视频上老师明显自己也没搞懂原理,于是我去寻找了答案。

/*
反编译之后的效果
*/
public static int m(){
	int i = 100;
	int j = i;
	i++;
	return j;
	Exception exception;
	exception;
	i++;
	throw exception;
}

这是反编译的结果,我是没怎么看懂。

看了一些文章后,才发现,原来这是一个涉及堆和栈的问题。

简单来说,就是try语句块中,return i 时,要返回的i值100先被缓存到一个局部变量中,后面虽然finally重新赋值,但返回的值不会受finally块中的影响。这就是基本变量放在栈中的问题。

看如下代码块,StringBuffer属于可修改的字符串,缓存返回的是地址值,输出结果就完全跟finally的规则一样了。

public class Test {
        public static void main(String[] args) {
                StringBuffer buffer = testFinally2();
                System.out.println(buffer);

        }
        private static StringBuffer testFinally2(){
                StringBuffer s = new StringBuffer("Hello");
                try {
                        return s;
                } catch (Exception e) {
                        return s;
                } finally {
                        s.append("World");
                }
        }
}

以上是浅显的个人理解,若有错误,欢迎指正和补充!

参考资料:blog.csdn.net/maijia0754/…