• try--catch--finally中return返回值执行的顺序(区别)


    1、try块中没有抛出异常,try、catch和finally块中都有return语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public static int NoException(){
             int i=10;
             try{
               System.out.println("i in try block is:"+i);
               return --i;
             }
             catch(Exception e){
               --i;
               System.out.println("i in catch - form try block is:"+i);
               return --i;
             }
             finally{     
               System.out.println("i in finally - from try or catch block is:"+i);
               return --i;
             }  
    }

    运行代码:

    1
    2
    3
    4
    5
    public static void main(String[] args) {
            System.out.println("=============NoException==================");
            System.out.println(NoException());
            System.out.println("===============================");   
    }

    运行结果:

    1
    2
    3
    4
    5
    =============NoException==================
    in try block is10
    in finally - from try or catch block is9
    8
    ===============================

    执行顺序:

       执行try块,执行到return语句时,先执行return的语句,--i,但是不返回到main方法,执行finally块,遇到finally块中的return语句,执行--i,并将值返回到main方法,这里就不会再回去返回try块中计算得到的值。

    结论:try-catch-finally都有return语句时,没有异常时,返回值是finally中的return返回的。从下面的字节码可以看出,try里的return将被忽略。

    2.try块中没有抛出异常,仅try和catch中有return语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public static int NoException1(){
                int i=10;
                try{
                    System.out.println("i in try block is:"+i);
                    return --i;
                }
                catch(Exception e){
                    --i;
                    System.out.println("i in catch - form try block is:"+i);
                    return --i;
                }
                finally{           
                    System.out.println("i in finally - from try or catch block is:"+i);
                    --i;
                    System.out.println("i in finally block is:"+i);
                    //return --i;
                }
    }

    运行结果:

    1
    2
    3
    4
    5
    6
    =============NoException1==================
    in try block is10
    in finally - from try or catch block is9
    in finally block is8
    9
    ===============================

    执行顺序:

       try中执行完return的语句后,不返回,执行finally块,finally块执行结束后,返回到try块中,返回i在try块中最后的值。

    结论:try-catch都有return语句时,没有异常时,返回值是try中的return返回的。

    通过字节码,我们发现,在try语句的return块中,return 返回的引用变量(i 是引用类型)并不是try语句外定义的引用变量i,而是系统重新定义了一个局部引用i'(29行标红色框的,系统在这里面用第三个变量保存当前的值),这个引用指向了引用i对应的值,也就是try ,即使在finally语句中把引用i指向了值减1,因为return的返回引用已经不是i 而是临时的iload_3,所以引用i的对应的值和try语句中的返回值无关了。 

    3.try块中抛出异常,try、catch和finally中都有return语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public static int WithException(){
                int i=10;
                try{
                    System.out.println("i in try block is:"+i);
                    i = i/0;
                    return --i;
                }
                catch(Exception e){
                    System.out.println("i in catch - form try block is:"+i);
                    --i;
                    System.out.println("i in catch block is:"+i);
                    return --i;
                }
                finally{           
                    System.out.println("i in finally - from try or catch block is--"+i);
                    --i;
                    System.out.println("i in finally block is--"+i);
                    return --i;
                }
    }

    执行结果:

    1
    2
    3
    4
    5
    6
    7
    8
    =============WithException==================
    in try block is10
    in catch - form try block is10
    in catch block is9
    in finally - from try or catch block is--8
    in finally block is--7
    6
    ===============================

    执行顺序:

       抛出异常后,执行catch块,在catch块的return的--i执行完后,并不直接返回而是执行finally,因finally中有return语句,所以,执行,返回结果6。

    结论:

       try块中抛出异常,try、catch和finally中都有return语句,返回值是finally中的return。

    4.try块中抛出异常,try和catch中都有return语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static int WithException1(){
                int i=10;
                try{
                    System.out.println("i in try block is:"+i);
                    i=i/0;
                    return --i;
                }catch(Exception e){
                    System.out.println("i in catch - form try block is:"+i);           
                    return --i;
                }finally{
                                                                                                                                                                          
                    System.out.println("i in finally - from try or catch block is:"+i);
                    --i;
                    System.out.println("i in finally block is:"+i);
                    //return i;
                }
    }

    执行结果:

    1
    2
    3
    4
    5
    6
    7
    =============WithException1==================
    in try block is10
    in catch - form try block is10
    in finally - from try or catch block is9
    in finally block is8
    9
    ===============================

    执行顺序:

       抛出异常后,执行catch块,执行完finally语句后,依旧返回catch中的执行return语句后的值,而不是finally中修改的值。

    结论:

       返回的catch中return值。

    5.try、catch中都出现异常,在finally中有返回

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public static int WithException2(){
                int i=10;
                try{
                    System.out.println("i in try block is:"+i);
                    i=i/0;
                    return --i;
                }
                catch(Exception e){
                    System.out.println("i in catch - form try block is:"+i);
                    int j = i/0;
                    return --i;
                }
                finally{
                                                                                           
                    System.out.println("i in finally - from try or catch block is:"+i);
                    --i;
                    --i;
                    System.out.println("i in finally block is:"+i);
                    return --i;
    }

    执行结果:

    1
    2
    3
    4
    5
    6
    7
    =============WithException2==================
    in try block is:10
    in catch - form try block is:10
    in finally - from try or catch block is:10
    in finally block is:8
    7
    ===============================

    执行顺序:   

       try块中出现异常到catch,catch中出现异常到finally,finally中执行到return语句返回,不检查异常。

    结论:

       返回finally中return值。

    6、只在函数最后出现return语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public static int WithException3(){
                int i=10;
                try{
                    System.out.println("i in try block is:"+i);
                    i=i/0;
                    //return --i;
                }
                catch(Exception e){
                    System.out.println("i in catch - form try block is:"+i);
                    //int j = i/0;
                    //return --i;
                }
                finally{
                                                                              
                    System.out.println("i in finally - from try or catch block is:"+i);
                    --i;
                    --i;
                    System.out.println("i in finally block is:"+i);
                    //return --i;
                }
                return --i;
    }

    执行结果:

    1
    2
    3
    4
    5
    6
    7
    =============WithException3==================
    in try block is10
    in catch - form try block is10
    in finally - from try or catch block is10
    in finally block is8
    7
    ===============================

    总体结论:

    结论一:

    (1)return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)

    (2)try、catch、finally语句中,在如果try语句有return语句,则返回的之后当前try中变量此时对应的值,此后对变量做任何的修改,都不影响try中return的返回值

    (3)如果finally块中有return 语句,则返回try或catch中的返回语句忽略。

    (4)如果finally块中抛出异常,则整个try、catch、finally块中抛出异常


    结论二:

       finally里面不建议放return语句,根据需要,return语句可以放在try和catch里面和函数的最后。可行的做法有四:
       (1)return语句只在函数最后出现一次。
       (2)return语句仅在try和catch里面都出现。
       (3)return语句仅在try和函数的最后都出现。
       (4)return语句仅在catch和函数的最后都出现。
       注意,除此之外的其他做法都是不可行的,编译器会报错。

    注意:

    (1)尽量在try或者catch中使用return语句。通过finally块中达到对try或者catch返回值修改是不可行的。

    (2)finally块中避免使用return语句,因为finally块中如果使用return语句,会显示的消化掉try、catch块中的异常信息,屏蔽了错误的发生

    (3)finally块中避免再次抛出异常,否则整个包含try语句块的方法回抛出异常,并且会消化掉try、catch块中的异常

    Reference

    [1] http://qing0991.blog.51cto.com/1640542/1387200

    [2] https://mp.weixin.qq.com/s?__biz=MzIxNjA5MTM2MA==&mid=2652434506&idx=1&sn=f62a0cc1a18c628e1a52979921184af4&chksm=8c620fc5bb1586d3fe093e03749d9879dbbc4d540f3a68eb18b16d97d973a80a292ba6f7a0c3&mpshare=1&scene=23&srcid=0304GBqHaOULDvnnqLVyCoCk#rd

  • 相关阅读:
    【更新】Java发送邮件:个人邮箱(QQ & 网易163)+企业邮箱+Android
    git pull 出现 WARNING: POSSIBLE DNS SPOOFING DETECTED!
    Redis解决“重试次数”场景的实现思路
    IDEA更改JavaScript版本
    npm与yarn命令
    SpringBoot+Vue前后端分离项目,maven package自动打包整合
    Vue(九)使用Ant Design入门——环境搭建
    Git常用命令
    Vue(八)全局变量和全局方法
    笔记本电池怎样使用问题
  • 原文地址:https://www.cnblogs.com/hoojjack/p/5873560.html
Copyright © 2020-2023  润新知