美文网首页Java基础
try catch finally的日常

try catch finally的日常

作者: 空格Ctrl | 来源:发表于2017-09-15 00:01 被阅读34次

    简书 勿纵
    转载请注明原创出处,谢谢!

    从这说起

    日常编码中,被问到一个有关try/catch/finally的执行顺序问题,如果在try中return的是一个有返回值的方法,那么try/catch/finally的执行顺序是怎样的?

    在分析上述问题之前,先用几个例子对try/catch/finally进行简要说明

    语法
         try {
            //将可能引发异常的代码写在try语句块中
         } catch (Exception e) {
            //捕获异常后进行后续处理,可有多个catch
         } finally {
            //无论是否有异常,finally中的语句块是必执行的。
            //finally可有可无,根据具体情况而定,一个try/catch/finally结构最多只能有一个finally
         }
    
    举例:

    案例1

         try {
            flag = "point1";
            System.out.println(flag);
            // throw new Exception();
         } catch (Exception e) {
            flag = "point2";
            System.out.println(flag);
         } 
    

    输出结果为:
    point1
    若在try语句块中加入throw new Exception();
    则输出结果为:
    point1
    point2
    即先执行try语句块,若try语句块中抛出异常再由catch捕获,执行catch语句块。若try语句块中在抛出异常的代码后还有语句,则这些语句不再执行。
    案例二

         try{
             flag = "point1";
             System.out.println(flag);
         }finally {
             flag = "point2";
             System.out.println(flag);
         }
    

    输出结果为:
    point1
    point2
    即先执行try语句块,再执行finally语句块。
    注意:try{}后面必须与catch或finally组合,否则编译不会通过。

    案例三

         try {
            flag = "point1";
            System.out.println(flag);
            throw new Exception();
         } catch (Exception e) {
             flag = "point2";
             System.out.println(flag);
         } finally {
              flag = "point3";
              System.out.println(flag);
         }
    

    输出结果为:
    point1
    point2
    point3
    即先执行try语句块,catch捕捉try中的异常后执行catch中的语句块,最后执行finally中的语句块。

    让return参与进来,就有了案例四和案例五。
    案例四

     @Test
     public void testMain(){
         System.out.println(test4());
      }
      public static String test4(){
         String flag;
         try {
            flag = "point1";
            System.out.println(flag);
            return flag;//throw new Exception();
         } catch (Exception e) {
            flag = "point2";
            System.out.println(flag);
            return flag;
         } finally {
            flag = "point3";
            System.out.println(flag);
         }
      }
    

    输出结果为:
    point1
    point3
    point1
    如果将try语句块中的return flag;注释掉,抛出异常throw new Exception();
    则输出的结果为:
    point1
    point2
    point3
    point2

    这个时候就有这么一个问题“为什么最后一个输出的值不是'point3'呢?”
    就案例4未注释掉return flag;,未抛异常情况的代码在编译后生成*.class文件代码如下

     @Test
     public void testMain() {
         System.out.println(test4());
     }
     public static String test4() {
         String flag;
         String var2;
         try {
             flag = "point1";
             System.out.println(flag);
             String e = flag;
             return e;
         } catch (Exception var6) {
             flag = "point2";
             System.out.println(flag);
             var2 = flag;
         } finally {
             flag = "point3";
             System.out.println(flag);
         }
         return var2;
     }
    

    即在try语句块正常执行,且存在返回值时,在执行return与finally方法之前,先将flag对象的值赋予e对象,在执行完finally方法后,回到try方法执行return e返回。

    若案例4注释掉return flag;,且抛出异常时,生成*.class文件中的代码如下

    @Test
     public void testMain() {
         System.out.println(test4());
     }
     public static String test4() {
         String flag;
         String var2;
         try {
             flag = "point1";
             System.out.println(flag);
             throw new Exception();
         } catch (Exception var6) {
             flag = "point2";
             System.out.println(flag);
             var2 = flag;
         } finally {
             flag = "point3";
             System.out.println(flag);
         }
         return var2;
     }
    

    即在捕捉try语句块中抛出的异常后执行catch语句块中代码,这里将flag的值赋值给var2,然后执行finally语句块,在try/catch/finally结构执行完毕后return var2。

    回到最初被问到的问题:如果在try中return的是一个有返回值的方法,那么try/catch/finally的执行顺序是怎样的?

    案例五

     @Test
     public void testMain(){
         System.out.println(test5());
     }
     public static String change(String flag){
         flag = "change";
         return flag;
     }
     public static String test5(){
         String flag;
         try {
             flag = "point1";
             System.out.println(flag);
             return change(flag);
         } catch (Exception e) {
             flag = "point2";
             System.out.println(flag);
             return flag;
         } finally {
             flag = "point3";
             System.out.println(flag);
         }
     }
    

    输出结果为:
    point1
    change
    point3
    change
    生成的*.class文件中相关代码如下

     @Test
     public void testMain() {
         System.out.println(test5());
     }
     public static String change(String flag) {
         flag = "change";
         System.out.println(flag);
         return flag;
     }
     public static String test5() {
         String flag;
         String var2;
         try {
             flag = "point1";
             System.out.println(flag);
             String e = change(flag);
             return e;
         } catch (Exception var6) {
             flag = "point2";
             System.out.println(flag);
             var2 = flag;
         } finally {
             flag = "point3";
             System.out.println(flag);
         }
         return var2;
     }
    

    这里其实和案例四相同,只是先将return的对象change()方法先执行得到返回值,再将返回值赋予e暂存,执行完finally语句块后return e。
    若try语句块中抛出异常,在catch语句块中return change(flag);,同理。

    初次写文章,多少会有一些不足之处,望建议与指正,谢谢。

    相关文章

      网友评论

        本文标题:try catch finally的日常

        本文链接:https://www.haomeiwen.com/subject/ewtjsxtx.html