在try catch finally 中有return时的返回结果

来源:互联网 发布:网络空间安全导论 pdf 编辑:程序博客网 时间:2024/06/18 05:45
结论:
  1、不管有木有出现异常,finally块中代码都会执行;
  2、当try和catch中有return时,finally仍然会执行;
  3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样, 返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
  4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
       5、如果finally 函数里面有return; 那么函数最终会返回finally 里面执行之后的return的值给函数,如果没有return,函数值会是try里面return的值,或者tatch里面的
return值。

举例:
  情况1:try{} catch(){}finally{} return;
            显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
         再执行finally块,最后执行try中return;
         finally块之后的语句return,因为程序在try中已经return所以不再执行。
情况3:try{ } catch(){return;} finally{} return;
         程序先执行try,如果遇到异常执行catch块,
         有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
                     最后执行catch块中return. finally之后也就是4处的代码不再执行。
         无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
          再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
          程序执行catch块中return之前(包括return语句中的表达式运算)代码;
          再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}//
          程序执行try块中return之前(包括return语句中的表达式运算)代码;
          有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
                       则再执行finally块,因为finally块中有return所以提前退出。
          无异常:则再执行finally块,因为finally块中有return所以提前退出。


最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
                  如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
                  编译器把finally中的return实现为一个warning。


 


 


下面是个测试程序
public class FinallyTest  
{
public static void main(String[] args) {
 
System.out.println(new FinallyTest().test());;
}


static int test()
{
int x = 1;
try
{
x++;
return x;
}
finally
{
++x;
}
}
}
结果是2。
分析:

在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,因此,即使finally中对变量x进行了改变,但是不会影响返回结果。它应该使用栈保存返回值。

package main;    import java.io.File;  import java.io.FileInputStream;  import java.io.IOException;    public class TestTryCatchFinally {        /**      * finally 中的代码 在try 或者 catch 语句中的 return 之情会被调用      *       */      public static void main(String[] args) {          // TODO Auto-generated method stub            System.out.println("testFinally1()最终返回值a=" + testFinally1());                    System.out.println("testFinally11()最终返回值a=" + testFinally11());                    System.out.println("testFinally12()最终返回值a=" + testFinally12());                    System.out.println("testFinally21()最终返回值a=" + testFinally21());                    System.out.println("testFinally22()最终返回值a=" + testFinally22());                    System.out.println("testFinally3()最终返回值a=" + testFinally3());                }        /* 没有遇到异常时候的结果 try-begin 10--in try try--end finally-begin 30--in finally finally-end 10      */      public static int testFinally1(){                    int a = 0;                    try {                            System.out.println("try-begin");              a=10;              //某一段业务逻辑,涉及到网络I/O  //          throw new IOException();               System.out.println(a+"--in try");              System.out.println("try--end");                            return a;                        }catch (Exception e) {                            System.out.println("catch-begin");              a = 20;              System.out.println(a+"--in catch");              System.out.println("catch-begin");                //          return a;          }finally{                            System.out.println("finally-begin");              a = 30;              System.out.println(a+"--in finally");              System.out.println("finally-end");          }          return a;      }      /* 没有遇到异常时候的结果 如果把return 放到了finally中那么无论有没有异常 返回值的都是 finally中的值 try-begin 10--in try try--end finally-begin 30--in finally finally-end 30      */      @SuppressWarnings("finally")      public static int testFinally11(){                    int a = 0;                    try {                            System.out.println("try-begin");              a=10;              //某一段业务逻辑,涉及到网络I/O  //          throw new IOException();               System.out.println(a+"--in try");              System.out.println("try--end");                            return a;                        }catch (Exception e) {                            System.out.println("catch-begin");              a = 20;              System.out.println(a+"--in catch");              System.out.println("catch-begin");                            return a;          }finally{                            System.out.println("finally-begin");              a = 30;              System.out.println(a+"--in finally");              System.out.println("finally-end");              return a;          }                }      /* 没有遇到异常时候的结果 try-begin 10--in try try--end finally-begin 30--in finally finally-end 30      */      public static int testFinally12(){                    int a = 0;                    try {                            System.out.println("try-begin");              a=10;              //某一段业务逻辑,涉及到网络I/O  //          throw new IOException();               System.out.println(a+"--in try");              System.out.println("try--end");                //          return a;                        }catch (Exception e) {                            System.out.println("catch-begin");              a = 20;              System.out.println(a+"--in catch");              System.out.println("catch-begin");                //          return a;          }finally{                            System.out.println("finally-begin");              a = 30;              System.out.println(a+"--in finally");              System.out.println("finally-end");          }                    return a;      }            /* 遇到IOException异常时候的结果 将最下面的 return a 注释掉时 try-begin catch-begin 20--in catch catch-begin finally-begin 30--in finally finally-end 20      */      public static int testFinally21(){                    int a = 0;                    try {                            System.out.println("try-begin");              a=10;              //某一段业务逻辑,涉及到网络I/O              throw new IOException("IO异常");  //          System.out.println(a+"--in try");  //          System.out.println("try--end");                //          return a;                        }catch (IOException e) {                            System.out.println("catch-begin");              a = 20;              System.out.println(a+"--in catch");              System.out.println("catch-begin");                            return a;          }finally{                            System.out.println("finally-begin");              a = 30;              System.out.println(a+"--in finally");              System.out.println("finally-end");          }            //      return a;      }      /*   重要级别! 遇到IOException异常时候的结果  未将最下面的 return a 注释掉,二将catch中的 return注释掉时 try-begin catch-begin 20--in catch catch-begin finally-begin 30--in finally finally-end 30      */      public static int testFinally22(){                    int a = 0;                    try {                            System.out.println("try-begin");              a=10;              //某一段业务逻辑,涉及到网络I/O              throw new IOException("IO异常");  //          System.out.println(a+"--in try");  //          System.out.println("try--end");                //          return a;                        }catch (IOException e) {                            System.out.println("catch-begin");              a = 20;              System.out.println(a+"--in catch");              System.out.println("catch-begin");                //          return a;          }finally{                            System.out.println("finally-begin");              a = 30;              System.out.println(a+"--in finally");              System.out.println("finally-end");          }                    return a;      }            /* 遇到其他Exception异常 但IOException却不能Catch到的时候 try-begin finally-begin 30--in finally finally-end Exception in thread "main" java.lang.ArithmeticException: / by zero     at main.TestTryCatchFinally.testFinally3(TestTryCatchFinally.java:168)     at main.TestTryCatchFinally.main(TestTryCatchFinally.java:22)  将try return打开,将catch return 注释 时 Exception in thread "main" java.lang.ArithmeticException: / by zero     at main.TestTryCatchFinally.testFinally3(TestTryCatchFinally.java:178)     at main.TestTryCatchFinally.main(TestTryCatchFinally.java:22) try-begin finally-begin 30--in finally finally-end      */      public static int testFinally3(){                    int a = 0;                    try {                            System.out.println("try-begin");              a=10;              //某一段业务逻辑,涉及到网络I/O              int b = a/0;              FileInputStream is = new FileInputStream(new File("D://mi.txt"));              System.out.println(a+"--in try");              System.out.println("try--end");                //          return a;                        }catch (IOException e) {                            System.out.println("catch-begin");              a = 20;              System.out.println(a+"--in catch");              System.out.println("catch-begin");                            return a;          }finally{                            System.out.println("finally-begin");              a = 30;              System.out.println(a+"--in finally");              System.out.println("finally-end");          }                    return a;      }        }  


原创粉丝点击