Java中finally是否改变try中return值

话不多说,直接上例子:

    

public class test {
        public static void main(String[] args){
            System.out.println(afresh());      //    0
        }
        static int afresh(){
            int xie=0;
            try{
                return xie;                     //   0
            }finally{
                xie=2;
                System.out.println("finally "+xie);   //finally 2
            }
        }
}

1. 明明在finally中修改了xie的值,为什么return回去的还是0,而在finally中删除的xie却是2?

很多人会去debug,但是这里debug的结果会和你预计有偏差:

 

 

2.明明debug都显示xie值更改为2了,为什么计算afresh()时依旧为0?

对于基本数据类来说,他的值传递很好理解,直接把数字拷贝一份赋值,在执行try语句块的return语句的时候,其实他的return语句执行了一半,可以理解为后半段执行了,将xie赋值给了return语句,但是前半段的return结束方法还没有执行,相当于数据库MVCC时的一个快照,将当前执行到这一步的xie变量的值生成一个快照保存下来给return副本,然后执行finally里面,xie变量的值确实变为2了,输出也是finally 2,但是finally执行完之后,会继续执行没有执行完的return前半段,此时,注意了,他返回的前面那个快照中的值,而不是后面经过finally修改的值,所以返回为0.

3.如果我们在finally中return一下又会是怎么样呢?

public class test {
        public static void main(String[] args){
            System.out.println(afresh());
        }
        static int afresh(){
            int xie=0;
            try{
                return xie;
            }finally{
                xie=2;
                System.out.println("finally "+xie);
                return xie;
            }
        }
}

 很明显,此时结果就是2了,因为try执行return的后半段保存快照后,就去执行finally里语句去了,finally遇到return直接就结束了,不会在让try语句再去执行return返回快照

4.上面的都是对于基本数据类型来说的,那么对于引用数据类型来说又是怎样呢?

我们先了解一下Java的传递方式:

在Java中,虽然不管是对于基本数据类型还是引用数据类型来说都是值传递,但是两者的值传递是有区别的,基本数据类型是直接传的字变量的值,拷贝了一份,而引用数据类型是把一个对象的地址拷贝了一份传递,很多人觉得(比如一个User,我把他传递给别人,但是别人修改了User里面的name,我这边的name也会改变)引用数据类型是引用传递,这是不对的,对于传递对象来说,举一个例子:

    

你有一把钥匙,当你的朋友想要去你家的时候,如果你直接把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。

你有一把钥匙,当你的朋友想要去你家的时候,你复刻了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。

但是,不管上面哪种情况,你的朋友拿着你给他的钥匙,进到你的家里,把你家的电视砸了。那你说你会不会受到影响?而我们在pass方法中,改变user对象的name属性的值的时候,不就是在“砸电视”么。你改变的不是那把钥匙,而是钥匙打开的房子。

所以在判断传递为引用对象时,应该判定的是该引用对象的地址是否改变,而不是其里面的内容。

详解:java面试3-对于java中值传递的理解(Hollis) - 我想回家 - 博客园

 修改代码:

public class test {
         static class User{
          String name;
          int age;
          public void setName(String name){
              this.name=name;
          }
         }
        public static void main(String[] args){
            System.out.println(afresh().name);
        }
        static User afresh(){
            User user = new User();
            user.setName("侨");
            try{
                user.setName("侨1");
                return user;
            }finally{
                user.setName("侨2");
                System.out.println("finally "+user.name);
            }
        }
}

 很明显,对于引用数据类型来说,finally里面修改数据,在try里面返回,依旧会改变,基于上面的解释,在try语句里面我们生成的是user的快照,他是一个地址值,我们也没有改变他,在finally里面我们只是改变他的一个属性值,所以返回拿到的是改变后的值。

注意点:

public class test {
         static class User{
          String name;
          int age;
          public void setAge(int age){
                 this.age=age;
          }
         }
        public static void main(String[] args){
            System.out.println(afresh().age);
        }
        static User afresh(){
            User user = new User();
            user.setAge(0);
            try{
                user.setAge(1);
                return user;
            }finally{
                user.setAge(2);
                System.out.println("finally "+user.age);
            }
        }
}
//对于age来说这样返回User的话也是一样的,但是我们看看下面的代码,不是返回User,而是返回User.age

public class test {
         static class User{
          String name;
          int age;
          public void setAge(int age){
                 this.age=age;
          }
         }
        public static void main(String[] args){
            System.out.println(afresh());
        }
        static int afresh(){
            User user = new User();
            user.setAge(0);
            try{
                user.setAge(1);
                return user.age;
            }finally{
                user.setAge(2);
                System.out.println("finally "+user.age);
            }
        }
}
//结果:

finally 2
1

//此时返回值是int类型,这时候和基本数据类型是等同的

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值