zoukankan      html  css  js  c++  java
  • try catch finally块中含有return语句时程序执行的几种情况

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17485221

     

        在这里看到了try catch finally块中含有return语句时程序执行的几种情况,但其实总结的并不全,而且分析的比较含糊。但有一点是可以肯定的,finally块中的内容会先于try中的return语句执行,如果finall语句块中也有return语句的话,那么直接从finally中返回了,这也是不建议在finally中return的原因。下面来看这几种情况。

    情况一(try中有return,finally中没有return):

    [java] view plain copy
     
    1. public class TryTest{  
    2.     public static void main(String[] args){  
    3.         System.out.println(test());  
    4.     }  
    5.   
    6.     private static int test(){  
    7.         int num = 10;  
    8.         try{  
    9.             System.out.println("try");  
    10.             return num += 80;  
    11.         }catch(Exception e){  
    12.             System.out.println("error");  
    13.         }finally{  
    14.             if (num > 20){  
    15.                 System.out.println("num>20 : " + num);  
    16.             }  
    17.             System.out.println("finally");  
    18.         }  
    19.         return num;  
    20.     }  
    21. }  

    输出结果如下:

    try
    num>20 : 90
    finally
    90

    分析:显然“return num += 80”被拆分成了“num = num+80”和“return num”两个语句,线执行try中的“num = num+80”语句,将其保存起来,在try中的”return num“执行前,先将finally中的语句执行完,而后再将90返回。

    情况二(try和finally中均有return):

    [java] view plain copy
     
    1. public class TryTest{  
    2.     public static void main(String[] args){  
    3.         System.out.println(test());  
    4.     }  
    5.   
    6.     private static int test(){  
    7.         int num = 10;  
    8.         try{  
    9.             System.out.println("try");  
    10.             return num += 80;  
    11.         }catch(Exception e){  
    12.             System.out.println("error");  
    13.         }finally{  
    14.             if (num > 20){  
    15.                 System.out.println("num>20 : " + num);  
    16.             }  
    17.             System.out.println("finally");  
    18.             num = 100;  
    19.             return num;  
    20.         }  
    21.     }  
    22. }  

    输出结果如下:

    try
    num>20 : 90
    finally
    100

    分析:try中的return语句同样被拆分了,finally中的return语句先于try中的return语句执行,因而try中的return被”覆盖“掉了,不再执行。

    情况三(finally中改变返回值num):

    [java] view plain copy
     
    1. public class TryTest{  
    2.     public static void main(String[] args){  
    3.         System.out.println(test());  
    4.     }  
    5.   
    6.     private static int test(){  
    7.         int num = 10;  
    8.         try{  
    9.             System.out.println("try");  
    10.             return num;  
    11.         }catch(Exception e){  
    12.             System.out.println("error");  
    13.         }finally{  
    14.             if (num > 20){  
    15.                 System.out.println("num>20 : " + num);  
    16.             }  
    17.             System.out.println("finally");  
    18.             num = 100;  
    19.         }  
    20.         return num;  
    21.     }  
    22. }  

    输出结果如下:

    try

    finally

    10

    分析:虽然在finally中改变了返回值num,但因为finally中没有return该num的值,因此在执行完finally中的语句后,test()函数会得到try中返回的num的值,而try中的num的值依然是程序进入finally代码块前保留下来的值,因此得到的返回值为10。

        

    但是我们来看下面的情况(将num的值包装在Num类中):

    [java] view plain copy
     
    1. public class TryTest{  
    2.     public static void main(String[] args){  
    3.         System.out.println(test().num);  
    4.     }  
    5.   
    6.     private static Num test(){  
    7.         Num number = new Num();  
    8.         try{  
    9.             System.out.println("try");  
    10.             return number;  
    11.         }catch(Exception e){  
    12.             System.out.println("error");  
    13.         }finally{  
    14.             if (number.num > 20){  
    15.                 System.out.println("number.num>20 : " + number.num);  
    16.             }  
    17.             System.out.println("finally");  
    18.             number.num = 100;  
    19.         }  
    20.         return number;  
    21.     }  
    22. }  
    23.   
    24. class Num{  
    25.     public int num = 10;  
    26. }  

    输出结果如下:

    try
    finally
    100

    从结果中可以看出,同样是在finally中改变了返回值num的值,在情况三中,并没有被try中的return返回(test()方法得到的不是100),但在这里却被try中的return语句返回了。

    对以上情况的分析,需要深入JVM虚拟机中程序执行exection_table中的字节码指令时操作栈的的操作情况,可以参考http://www.2cto.com/kf/201010/76754.html这篇文章,也可以参考《深入Java虚拟机:JVM高级特性与最佳实践》第6章中对属性表集合的讲解部分。

    对于含有return语句的情况,这里我们可以简单地总结如下:

        try语句在返回前,将其他所有的操作执行完,保留好要返回的值,而后转入执行finally中的语句,而后分为以下三种情况:

        情况一:如果finally中有return语句,则会将try中的return语句”覆盖“掉,直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。

        情况二:如果finally中没有return语句,也没有改变要返回值,则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。

        情况三:如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况,:

            1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。

            2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。

  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/lenbore/p/7989690.html
Copyright © 2011-2022 走看看