• Try,Catch,Finally三块中如果有Return是怎么个运行顺序


         今天看一个Java SSH的面试题,题目大概意思是:try、catch中存在return语句,还会执行finally块吗?如果执行,是return先执行还是finally先执行?如果有多个return语句,结果如何?

         看了以后我还真犯嘀咕,做了软件开发这些年,还没认真思考过则个问题,于是赶紧写个测试测试代码如下:

     1 class Program
     2     {
     3         public static int a = 0;
     4         static void Main(string[] args)
     5         {
     6             var result = GetValue();
     7         }
     8 
     9         public static int GetValue()
    10         {
    11             try
    12             {
    13                 a = 2;
    14                 throw new Exception();
    15             }
    16             catch (Exception ex)
    17             {
    18                 a = 3;
    19                 return a;
    20                 a = 4;
    21             }
    22             finally
    23             {
    24                 a = 5;
    25             }
    26         }
    27     }

    为了探究个明白,使用ILSpy工具查看IL代码, GetValue()的IL代码如下:

     1 .method public hidebysig static 
     2     int32 GetValue () cil managed 
     3 {
     4     // Method begins at RVA 0x2064
     5     // Code size 42 (0x2a)
     6     .maxstack 1   
     7     .locals init (   
     8         [0] class [mscorlib]System.Exception ex,//定义Exception类型变量 ex
     9         [1] int32 CS$1$0000                     //定义int32类型变量 CS$1$000        
    10     )
    11 
    12     IL_0000: nop                                //No Operation 没有任何操作
    13     .try
    14     {
    15         .try
    16         {
    17             IL_0001: nop
    18             IL_0002: ldc.i4.2                   //把int32 类型的数据2 推入计算堆栈上
    19             IL_0003: stsfld int32 ConsoleApplication1.Program::a                      //用计算堆栈的值替换静态字段a的值
    20             IL_0008: newobj instance void [mscorlib]System.Exception::.ctor()         //实例化Exception对象,并将对象推入到计算堆栈上
    21             IL_000d: throw                      //引发当前位于计算堆栈上的异常对象
    22         } // end .try
    23         catch [mscorlib]System.Exception
    24         {
    25             IL_000e: stloc.0                    //从计算堆栈的顶部弹出当前值(Exception对象)并将其存储到索引 0 处的局部变量列表中
    26             IL_000f: nop
    27             IL_0010: ldc.i4.3                   //把整数类型3推入计算堆栈上
    28             IL_0011: stsfld int32 ConsoleApplication1.Program::a                     //用计算堆栈的值置换静态变量a的值
    29             IL_0016: ldsfld int32 ConsoleApplication1.Program::a                     //将静态字段a的值推入计算堆栈上
    30             IL_001b: stloc.1                    //从计算堆栈的顶部弹出当前值,并将其存储到索引 1 处的局部变量列表中
    31             IL_001c: leave.s IL_0027            //退出受保护的代码区域,无条件将控制转移到目标指令 [ leave.s 指令清空计算堆栈并确保执行周围适当的 finally 块。]
    32         } // end handler
    33     } // end .try
    34     finally
    35     {
    36         IL_001e: nop
    37         IL_001f: ldc.i4.5                       //把整数5推入计算堆栈上
    38         IL_0020: stsfld int32 ConsoleApplication1.Program::a                        //用计算对象韩的值置换静态变量a的值
    39         IL_0025: nop
    40         IL_0026: endfinally                     //将控制从异常块的 fault 或 finally 子句转移回公共语言结构 (CLI) 异常处理程序。
    41     } // end handler
    42 
    43     IL_0027: nop
    44     IL_0028: ldloc.1                            //将索引 1 处的局部变量加载到计算堆栈上
    45     IL_0029: ret                                //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上
    46 } // end of method Program::GetValue

    通过IL代码和相关的注释,基本可以看出他们的执行流程,猜测出这个方法返回的结果以及静态变量a最后的值是多少。

    最后GetValue()方法返回的结果是3;静态变量a的值是5;

    但是 “IL_001c: leave.s IL_0027 ”  leave.s 还没看明白怎么回事?有相关熟悉的人,请指点,谢谢!

    另外问题提到:有多个return的情况,返回哪个return的结果?  我试了一下,没有发现允许执行多次return的可能!如果有请不吝指出!

  • 相关阅读:
    vue+element ui 实现菜单无限极菜单
    DOM事件绑定原理和传播机制
    数组和对象的深浅克隆
    new源码分析和Object.create的重写
    原型和原型链的学习
    4.3 模型参数的延后初始化
    4.2 模型参数的访问、初始化和共享
    CSAPP Float Point
    4.1 模型构造
    3.16 实战Kaggle比赛:房价预测
  • 原文地址:https://www.cnblogs.com/beixing/p/4160298.html
Copyright © 2020-2023  润新知