zoukankan      html  css  js  c++  java
  • 关于 try..catch..finally

    那天中午和同事讨论起c#中的try..catch..finally. 据说有人分析IL发现这块的运行逻辑和原来C++中是不同的( 注1 ). 于是这个原本很清晰的问题在我头脑中又模糊起来. 本着实践出真知的原则, 我特意写了一小段代码调查了一下, 现将结果拿出来与大家分享.

     1     class Program {
     2         static void Main(string[] args) {
     3             try {
     4                 int i = new Program().Test();
     5                 Console.WriteLine(i);
     6             }
     7             catch { }
     8         }
     9 
    10         public int Test() {
    11             int i = 0;
    12             try {
    13                 i = int.Parse("2");
    14                 return i;
    15             }
    16             catch {
    17                 i = -1;
    18                 throw new Exception(i.ToString());
    19             }
    20             finally {
    21                 i = 1;
    22             }
    23             return i;
    24         }
    25     }

    运行代码,  发现Test函数中是这样运行的:

    1. 行号: 11 -> 12 -> 13 -> 14 -> 20 -> 21 -> 22 -> 24.
    最终返回结果为2. 也就是说当try块中的代码全部运行完之后, 又跳转到finally块中运行, 完成后直接返回try块中的值.

    2. 将上述代码中第14行的 " return i; " 注释掉, 运行顺序变成: 11 -> 12 -> 13 -> 20 -> 21 -> 22 -> 23 -> 24.
    最终返回结果为1. 也是先运行完整个try块, 再运行finally块, 最后return.

    3. 最后将上述代码第13行改成 " i = int.Parse("2a"); " 制造一个异常. 发现运行顺序变成: 11 -> 12 ->13 -> 16 -> 17 -> 18 -> 20 -> 21 -> 22.
    最终抛出异常. 这说明程序是先运行try块, 发现异常后运行catch块, 在离开catch块之前先运行finally块. 然后直接抛出18行的异常.

    综合上述三种情况, 我发现其实finally块就是一段独立的代码. 无论是try块还是catch块, 在离开前都会跳转去执行finally中的代码. 但是此时try和catch中的所有代码都已经执行完毕, 因此在运行finally时是不会对前面的结果造成任何影响的. 如此说来编译器不许我们将return之类的代码放到finally中就是很好理解的事情了. ^_^

    注1: 在标准C++中是没有finally的, 只有try和catch. 但是在VC中有宏 _try.._except.._finally 可以实现相同的效果. 呵呵, 感谢江南同志!
  • 相关阅读:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    14.18 InnoDB Backup and Recovery 备份和恢复:
    php使用 _before_index() 来实现访问页面前,判断登录
    php使用 _before_index() 来实现访问页面前,判断登录
    查询方式实例演示
    查询方式实例演示
    haproxy timeout server 46000 后台超时时间
    haproxy timeout server 46000 后台超时时间
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
    14.10.5 Reclaiming Disk Space with TRUNCATE TABLE 回收空间使用TRUNCATE TABLE
  • 原文地址:https://www.cnblogs.com/iamzyf/p/812680.html
Copyright © 2011-2022 走看看