finally能不能影响try的return值

大家都知道try、finally代码块之间的执行顺序,finally总是会在try之后执行的,但是try中有retrun的时候,会不会被finally影响呢。

首先是返回基本数据类型的情况。

1、return语句在try中,finally中改变i的值,retrun的结果会不会变

@Test
    void loads() {
        System.out.println("返回结果:"+tryReturn());
    }

    int tryReturn(){
        int i = 0;
        try {
            i ++;
            System.out.println("进入try语句,i="+i);
            return i;
        }finally {
            i ++;
            System.out.println("进入finally语句,i="+i);
        }
    }

执行结果:

finally中不能改变return的值。

2、try中有return语句,finally中也有return语句,到底会返回哪个

@Test
    void loads() {
        System.out.println("返回结果:"+tryReturn());
    }

    int tryReturn(){
        int i = 0;
        try {
            i ++;
            System.out.println("进入try语句,i="+i);
            return i;
        }finally {
            i ++;
            System.out.println("进入finally语句,i="+i);
            return i;
        }
    }

执行结果:

很明显,是finally中的 return语句返回的值。

3、以下是返回String类型的情况,这里给i赋值的是字面量。

@Test
    void loads() {
        System.out.println("返回结果:"+tryReturn());
    }

    String tryReturn(){
        String i = "初始值";
        try {
            i = "i为try语句";
            System.out.println("进入try语句,"+i);
            return i;
        }finally {
            i = "i为finally语句";
            System.out.println("进入finally语句,"+i);
        }
    }

执行结果:

返回的是try中的retrun执行的结果。 

4、以下是返回自定义类型的情况。

@Test
    void loads() {
        System.out.println("返回结果:"+tryReturn());
    }

    User tryReturn(){
        User user;
        try {
            user = new User("李闪闪");;
            System.out.println("进入try语句,"+user);
            return user;
        }finally {
            user = new User("张三");
            System.out.println("进入finally语句,"+user);
        }
    }

 

可以看到user还是那个user。

5、改变引用类型的属性值,也就是这里改变user的name会怎么样呢

@Test
    void loads() {
        User user = tryReturn();
        System.out.println("返回结果:"+user+":"+user.getName());
        System.out.println(user.getName());
    }

    User tryReturn(){
        User user = null;
        try {
            user = new User("李闪闪");;
            System.out.println("进入try语句,"+user+":"+user.getName());
            return user;
        }finally {
            user.setName("张三");
            System.out.println("进入finally语句,"+user.getName());
        }
    }

执行结果:

可以看到,user还是那个user,但是属性却变了。

总结:

1、try的return先执行,执行的结果会被保存在局部变量中,finally在try的return执行完了后再执行,finally执行完了之后,返回保存在局部变量中的值。局部变量在栈帧中,不懂栈帧的话需要去看JVM的栈。

2、try和finally都有retrun的情况下,也遵循第1条,但是执行到finally的return语句,程序终止了,也就没有了返回保存在局部变量中的值那一步。对return可以终止程序不了解的话可以去看讲述这个的其他博客。

3、返回值是基本数据类型的情况,保存在局部变量中的执行的结果值。但返回的是引用类型的话 ,保存在局部变量的是引用的地址值,例如user的示例。

4、finally改变对象的属性值可以影响try的return,如上第6个实例。局部变量保存了user指向的堆中地址值,但是finally改变的是堆中user真实对象的属性name指向常量池的字符串地址值,所以能够影响到try的return值。如果是数组和StringBuilder这种可变字符串同理。对于这条如果不理解的话需要去看JVM,了解堆栈常量池,弄懂对象是怎么存储的。

最后是官方文档对于try和return的一些解释,下面是翻译后的截图和网址:

Chapter 4. The class File Formaticon-default.png?t=LA92https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.2.5

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值