浅析Java try....catch....finally中return语句执行顺序

原创 2017年05月19日 22:59:14

浅析Java try….catch….finally中return语句执行顺序

最近看到一道JAVA笔试题:“try{..}中有return语句,那么紧跟在try后的finally{..}的code会不会执行,什么时候执行?”
finally内的code会执行,但是什么时候执行就难以确定,于是运行一段程序后觉得是在return语句执行后,return语句返回前执行,看代码清楚些

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(new Test().test());
    }
    public int test(){
        int i=1;
        try{
            System.out.println("try....");
            return i+=2;
        }
        finally{
            System.out.println("finally....");
            i+=3;
            System.out.println(i);
        }
    }
}

运行结果:
try….
finally….
6
3
根据运行结果可知try{..}先运行,并且return后的expression:i+=2也运行了,此时i=3,再运行finally{…}的代码。此时i=6,但是返回的值却是3;
这就涉及到java方法在栈幀中执行过程,
具体参考http://blog.csdn.net/zq602316498/article/details/38926607
java方法是在栈帧中执行,栈帧是线程私有栈的单位,执行方法的线程会为每一个方法分配一小块栈空间来作为该方法执行时的内存空间,栈帧分为三个区域:
1. 操作数栈,用来保存正在执行的表达式中的操作数。
2. 局部变量区,用来保存方法中使用的变量,包括方法参数,方法内部声明的变量,以及方法中使用到的对象的成员变量或类的成员变量(静态变量),最后两种变量会复制到局部变量区。
3. 字节码指令区,这个不用解释了,就是方法中的代码翻译成的指令。
return语句
eturn expression是分成两部分执行的:
执行:expression;
执行:return指令;
例如:return x+y;
这句代码先执行x+y,再执行return;首先执行将x以及y从局部变量区复制到操作数栈顶的指令,然后执行加法指令,这个时候结果x+y的值会保存在操作数栈的栈顶,最后执行return指令,返回操作数栈顶的值。
如果方法中有finally语句块,那么return语句又是如何执行的呢?
例如下面这段代码:
try{
return expression;
}finally{
code…..;
}
首先我们知道,finally语句是一定会执行,但他们的执行顺序是怎么样的呢?他们的执行顺序如下:
1、expression,计算该表达式,结果保存在操作数栈顶;
2、操作数栈顶值(expression的结果)复制到局部变量区作为返回值;
3、finally语句块中的代码;
4、将第2步复制到局部变量区的返回值又复制回操作数栈顶;
5、return指令,返回操作数栈顶的值;
我们可以看到,在第一步执行完毕后,整个方法的返回值就已经确定了,由于还要执行finally代码块,因此程序会将返回值暂存在局部变量区,腾出操作数栈用来执行finally语句块中代码,等finally执行完毕,再将暂存的返回值又复制回操作数栈顶。所以无论finally语句块中执行了什么操作,都无法影响返回值,所以试图在finally语句块中修改返回值是徒劳的。因此,finally语句块设计出来的目的只是为了让方法执行一些重要的收尾工作,而不是用来计算返回值的。
所以运行结果返回值为3,而不是6。finally语句在return语句执行后,return语句返回前执行。

如果finally{….}中有return 语句呢?

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(new Test().test());
    }
    public int test(){
        int i=1;
        try{
            System.out.println("try....");

            return i+=2;
        }
        finally{
            System.out.println("finally....");
            i+=3;
            System.out.println(i);
            return i;
        }
    }
}

运行结果:
try….
finally….
6
6
try中的return 被finally 中的return 覆盖。

如果catch{….}中有return 语句呢

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(new Test().test());
    }
    public int test(){
        int i=1;
        try{
            System.out.println("try....");
            i/=0;
            i+=2;
            return i;
        }catch(Exception e){
            System.out.println("catch....");
            i+=1;
            return i;
        }
        finally{
            System.out.println("finally....");
            i+=3;
            System.out.println(i);
        }
    }

运行结果:
try….
catch….
finally….
5
2
先运行try{..},此时i/=0;抛出异常,catch捕捉异常并执行catch{…},执行return语句后,执行完finally{…},return 返回 i 值。并且 i 值不受finally的影响。

如果try….catch….finally中都有return语句呢

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(new Test().test());
    }
    public int test(){
        int i=1;
        try{
            System.out.println("try....");
            i+=2;
            return i;
        }catch(Exception e){
            System.out.println("catch....");
            i+=1;
            return i;
        }
        finally{
            System.out.println("finally....");
            i+=3;
            System.out.println(i);
            return i;
        }
    }
}

运行结果
try….
finally….
6
6

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(new Test().test());
    }
    public int test(){
        int i=1;
        try{
            System.out.println("try....");
            i/=0;
            i+=2;
            return i;
        }catch(Exception e){
            System.out.println("catch....");
            i+=1;
            return i;
        }
        finally{
            System.out.println("finally....");
            i+=3;
            System.out.println(i);
            return i;
        }
    }
}

运行结果
try….
catch….
finally….
5
5
可以看出,不管有无异常,finally的return语句都会进行覆盖。
最后总结:finally块的语句在try或catch中的return语句执行之后返回之前执行,且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值,若finally里也有return语句则覆盖try或catch中的return语句直接返回

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

try-catch语句中return和finally执行顺序详解

刷java面试题偶然看到这类问题(try/finally中含有return时的执行顺序),觉得挺有意思于是小小的研究了一下,希望经过我添油加醋天马行空之后,能给你带来一定的帮助 原题 try {...

黑马程序员 try或catch中存在return 语句时,它们与finally 的执行顺序问题

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------...

含有return语句的try-catch-finally语句执行顺序

import java.io.*; public class Mine{ public int method0(){ try{ FileInpu...

Java try/catch/finally代码块中加入return后的执行顺序问题

finally可以分两方面理解 1.执行时机问题。finally总会执行(除非是System.exit()),正常情况下在try后执行,抛异常时在catch后面执行 2.返回值问题。可以认...

Java含有return 的try catch finally的执行顺序

1、try-catch-finally执行顺序: 一、执行try{}块; 二、如果try{}块有异常产生,执行catch{}块; 三、无论有没有异常都要执行finally{}块,这里可以看出只要...

Java-有return的情况下try catch finally的执行顺序(最有说服力的总结)

结论: 1、不管有木有出现异常,finally块中代码都会执行; 2、当try和catch中有return时,finally仍然会执行; 3、finally是在return后面的表达式运算后执行的(此...
  • ko_tin
  • ko_tin
  • 2016年11月29日 00:17
  • 150

java 有return的情况下try catch finally的执行顺序

结论: 1、不管有木有出现异常,finally块中代码都会执行; 2、当try和catch中有return时,finally仍然会执行; 3、finally是在return后面的表达式运算后执行的(此...
  • eunyeon
  • eunyeon
  • 2016年10月21日 09:54
  • 148

Java异常捕获之try-catch-finally-return的执行顺序

情况1:try块中没有抛出异常try和finally块中都有return语句 public static int NoException(){ int i=10; try{ S...
  • aaoxue
  • aaoxue
  • 2013年01月23日 21:45
  • 11071

Android面试之java基础try-catch-finally-return的执行先后顺序问题

还是一个被个程序猿们讨论多时的问题,也是众软件公司面试题中很钟情的一个问题,更是一个考查程序猿对Java基础知识掌握理解程度的问题,就是本文要说的try-catch-finally-return的执行...

关于Java中try-catch-finally-return的执行顺序

1、try块中没有抛出异常,try、catch和finally块中都有return语句 1 2 3 4 5 6 7 8 9...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:浅析Java try....catch....finally中return语句执行顺序
举报原因:
原因补充:

(最多只允许输入30个字)