浅析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语句直接返回

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangjjuan/article/details/72547797

mysql sql语句调优

-
  • 1970年01月01日 08:00

java中异常处理finally和return语句的执行顺序

finally代码块的语句在return之前一定会得到执行 如果try块中有return语句,finally代码块没有return语句,那么try块中的return语句在返回之前会先将要返回的值保存,...
  • shihui512
  • shihui512
  • 2016-06-14 19:36:12
  • 2107

java中finally与return的执行顺序详解

一些准备知识:     首先为了说明白java中finally与return的执行顺序是怎样的这个问题,我们需要做一点准备工作。     java方法是在栈幀中执行,栈幀是线程私有栈的单位,执行方法的...
  • qj19842011
  • qj19842011
  • 2015-05-12 21:16:16
  • 6804

try中return语句与finally语句执行顺序

 在这里看到了try catch finally块中含有return语句时程序执行的几种情况,但其实总结的并不全,而且分析的比较含糊。但有一点是可以肯定的,finally块中的内容会先于tr...
  • lucyxu107
  • lucyxu107
  • 2017-06-14 15:16:02
  • 184

Java中的Static块与静态方法

  • 2012年06月01日 17:14
  • 2KB
  • 下载

try-catch-finally-return执行顺序

1,try-catch-finally执行顺序: ①,执行try{}块 ②,如果try{}块有异常产生,执行catch{}块 ③,无论有没有异常都要执行finally{}块,这里可以...
  • riledog
  • riledog
  • 2016-07-25 13:31:11
  • 156

Java中finally语句块的深度解析(try catch finally的执行顺序)

首先摆出结论: 1、除了以下2种情况外,不管有木有出现异常,finally块中代码都会执行; ①程序未进入try{}块的执行,如在try之前出现运行时异常,程序终止。 ②程序进入到try{}和c...
  • u014475796
  • u014475796
  • 2016-11-08 22:25:10
  • 1024

return语句在try-catch-finally中的执行顺序

return语句在try-catch-finally中的执行顺序,这个问题很早在Q群上听闻,今天结合网上资料以及自己的实践,大体明白了:在try范围执行时抛出异常后,try里面剩余的代码不再执行,直接...
  • chenshizero
  • chenshizero
  • 2010-05-17 21:47:00
  • 764

一道Java笔试题:静态语句块、构造语句块和构造函数的执行顺序

public class HelloA { //构造方法 public HelloA(){ System.out.println("Hello A!父类构造方法"); } //非静态代码块...
  • qq_21856521
  • qq_21856521
  • 2016-11-03 23:13:16
  • 1342
收藏助手
不良信息举报
您举报文章:浅析Java try....catch....finally中return语句执行顺序
举报原因:
原因补充:

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