java中关于try, catch, finally中的细节分析

本文通过几个示例程序详细解析了Java中finally块对方法返回值的影响,区分了基本数据类型与引用数据类型的处理方式,并总结了finally块中有无return语句时的不同行为。

首先来看一个程序(finally块中有return)

    public static int test(){
        int i = 0;
        try{
            i = 1;
            System.out.println("try i= "+i);
            return i;
        }catch (Exception e){
            i = 2;
            return i;
        }finally {
            i = 3;
            System.out.println("finally i= "+i);
            return i;
        }
    }

运行结果是

try i= 1
finally i= 3
3

我们打上断点看一下 i 的变化过程

  1. 第一步是在 try 中, return时 i : 1
  2. 由于这个程序没有出现异常, catch中的代码块不执行
  3. 进入到 finally 中, 此时 输出和return都发生了变化 , i 变成了 3 
  4. test输出的结果3

结论: 此时test方法的返回值是3, 在try, catch中的返回值被finally的返回值给屏蔽掉了, 所以如果finally中有return则会屏蔽方法中的返回值

再来看一个程序(finally中无return)

    public static int test1(){
        int i = 0;
        try{
            i = 1;
            System.out.println("try i="+i);
            return i;
        }catch (Exception e){
            i = 2;
            return i;
        }finally {
            i = 3;
            System.out.println("finally i="+i);
        }
    }

运行结果是

try i= 1
finally i= 3
1

同样打上断点看一下变化过程

  1. 第一步还是在try中, 这时 i 是 1, return 的结果是 i : 1
  2. 程序中没有出现异常, catch中的代码块不会执行
  3. 进入到finally中, i 受到了影响, 值改变了, 变成了3
  4. test输出的结果仍然是1

结论: 根据结果可以看到方法test的返回值不受finally中的影响, 但是变量i还是受到了影响, 它的值改变了, 返回值是放在栈中的, return就是把返回值压栈了, 相当于一个临时变量, 在finally中并不会影响返回值

再看一个程序 (finally中有return)

    public static ExceptionTest test2(){
        ExceptionTest exceptionTest = new ExceptionTest();
        try{
            exceptionTest.age = 1;
            System.out.println("try age= "+exceptionTest.age);
            return exceptionTest;
        }catch (Exception e){
            exceptionTest.age = 2;
            return exceptionTest;
        }finally {
            exceptionTest.age = 3;
            System.out.println("finally age= "+exceptionTest.age);
            return exceptionTest;
        }
    }

运行结果是

try age= 1
finally age= 3
3

接下来去掉return

    public static ExceptionTest test2(){
        ExceptionTest exceptionTest = new ExceptionTest();
        try{
            exceptionTest.age = 1;
            System.out.println("try age= "+exceptionTest.age);
            return exceptionTest;
        }catch (Exception e){
            exceptionTest.age = 2;
            return exceptionTest;
        }finally {
//            exceptionTest = new ExceptionTest();
            exceptionTest.age = 3;
            System.out.println("finally age= "+exceptionTest.age);
        }
    }

运行结果是

try age= 1
finally age= 3
3

以上这两个例子都可以看到finally有没有return都会对返回值产生影响

总结:

在finally和try中对数据进行操作时, 要把数据分为基本数据类型和引用数据类型. 他们存在的地方不一样, 一个是栈区, 另一个是堆区

对于基本数据类型

  • 在异常体系中, 若finally中存在return, 则try, catch中的语句失效

  • 若finally中无return, try和catch中有, 则try, catch代码块先暂存代码块中的值, 然后执行finally代码块, 最后返回暂存值

对于引用数据类型

  • 堆中存放了内存地址, 所以改变的不是地址, 而是地址的内容

  • 所以无论finally中有无return, 都会对当前方法的返回值产生影响. 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值