finally语句到底在return之前还是之后执行?

finally语句的执行有一定前提,需执行到try语句。如果在try语句之前就返回,finally语句必然不会执行。此外,在执行try语句过程中,终止JVM也不会执行finally语句。所以,在finally语句块执行的前提下,讨论finally语句到底在return之前还是之后呢? 在这里分了以下几种情况来分析:

1.情况1,就是try中的return语句先执行但并没有立即返回,其次finally块中的语句执行,最后try中return返回。

public class Test {
    public static void main(String[] args) {
        System.out.println(test());
    }
    public static int test(){
        int num = 10;
        try {
            System.out.println("try doing...");
            return num += 10;
        }catch (Exception e){
            System.out.println("catch doing...");
        }finally {
            System.out.println("finally doing...");
            if (num > 15){
                System.out.println("num > 15, num = " + num);
            }
        }
        return 100;  //不可达
    }
}

运行结果:

try doing...
finally doing...
num > 15, num = 20
20

其过程是,try中的return语句num += 10先执行,num = 20,但该return语句没有将结果直接返回,而是执行finally语句块的语句,打印“finally doing…”,以及if语句打印“num > 15, num = 20”,执行完finally块内容。最后,return返回try中的结果。(在此说下,Java中到底是传值还是传址?详情见)

2.情况2,finally中的return语句会覆盖try中return的结果

public class Test {
    public static void main(String[] args) {
        System.out.println(test());
    }
    public static int test(){
        int num = 10;
        try {
            System.out.println("try doing...");
            return num += 10;
        }catch (Exception e){
            System.out.println("catch doing...");
        }finally {
            System.out.println("finally doing...");
            if (num > 15){
                System.out.println("num > 15, num = " + num);
            }
            return 30;
        }
    }
}

运行结果:

try doing...
finally doing...
num > 15, num = 20
30

其过程是,try中的return语句num += 10依旧先执行,num = 20,该return语句没有将结果直接返回,继续执行finally语句块的语句,打印“finally doing…”,以及if语句打印“num > 15, num = 20”,后执行finally中的return语句并将30作为结果返回,从而造成了try中返回的结果num=20被覆盖。

3.情况3,如果finally语句中没有return语句覆盖返回值,那么原来的返回值是否会改变?

其实这与Java参数传递方式是相似的(均为值传递),“返回值”均不会改变,这里的“返回值”有两层含义

如果返回的是基本数据类型,没有return语句覆盖返回值时,原来的返回值不会改变。注意,此处的返回值指的是 try语句块 中变量num所指向的存储单元的内容。(num = 20,返回的是20)。

public class Test {
    public static void main(String[] args) {
        System.out.println(test());
    }
    public static int test(){
        int num = 10;
        try {
            System.out.println("try doing...");
            return num += 10;  //返回的是num所对应存储单元的内容,即20
        }catch (Exception e){
            System.out.println("catch doing...");
        }finally {
            System.out.println("finally doing...");
            if (num > 15){
                System.out.println("num > 15, num = " + num);
            }
            num = 100;
            System.out.println(num);
        }
        return 0;
    }
}

运行结果:

try doing...
finally doing...
num > 15, num = 20
100
20

返回的是引用数据类型,没有return语句覆盖返回值时,原来的返回值也不会改变。注意,此处的返回值指的是 try语句块中 引用变量sb所指向的存储单元的内容,内容是对象的地址值

public class Test {
    public static void main(String[] args) {
        System.out.println(test().toString()); //4. 访问的是0x0001所指的对象
    }
    public static StringBuffer test(){
        StringBuffer sb = new StringBuffer("Kyrie");//1. 假设0x0001是创建的对象地址值
        try {
            System.out.println("try doing...");
            return sb;  //2. sb->0x0001,返回的是sb所对应存储单元的内容,即0x0001
        }catch (Exception e){
            System.out.println("catch doing...");
        }finally {
            System.out.println("finally doing...");
            sb.append("2011");
            sb = new StringBuffer("6666");  //3. 此处,相当于sb指向了一个新对象,新对象的地址值为0x1000,那么sb所指存储单元内容为0x1000
            System.out.println(sb.toString());
        }
        return null;
    }
}

运行结果:

try doing...
finally doing...
6666
Kyrie2011

4.情况4,try块里的return语句在异常的情况下不会被执行

public class Test{
    public static void main(String[] args) {
        System.out.println(test());
    }
    public static int test(){
        int num = 10;
        try {
            System.out.println("doing try。。。");
            num = num / 0;
            return num += 100;  //不会被执行
        }catch (Exception e){
            num += 10;
            System.out.println("doing catch, num = " + num);
        }finally {
            if (num > 15){
                System.out.println(" num > 15, num = " + num);
            }
        }
        return -1;
    }
}

运行结果:

doing try。。。
doing catch, num = 20
 num > 15, num = 20
-1

从上述结果可看出,try中发生的异常时,try中的return语句不会被执行。

5.情况5,当发生异常后,catch中的return执行情况与未发生异常时try中return的执行情况完全一样

public class Test {
    public static void main(String[] args) {
        System.out.println(test());
    }
    public static int test(){
        int num = 10;
        try {
            System.out.println("doing try。。。");
            num = num / 0;
            return num += 100;
        }catch (Exception e){
            System.out.println("doing catch, num = " + num);
            return num += 40; //先执行 num+=40,此时num所指向的存储单元的内容为40
        }finally {
            if (num > 15){
                System.out.println(" num > 15, num = " + num);
            }
            num += 1000;
        }
    }
}

运行结果:

doing try。。。
doing catch, num = 10
 num > 15, num = 50
50

过程是发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完后catch中的return再返回结果,finally里对num的改变对返回值无影响,原因同前面一样,也就是说情况与try中的return语句执行完全一样。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值