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

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

 class Program
{
public static int a = ;
static void Main(string[] args)
{
var result = GetValue();
} public static int GetValue()
{
try
{
a = ;
throw new Exception();
}
catch (Exception ex)
{
a = ;
return a;
a = ;
}
finally
{
a = ;
}
}
}

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

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

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

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

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

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

Try,Catch,Finally三块中如果有Return是怎么个运行顺序的更多相关文章

  1. finally不管有没有错都会运行 finally 块用于清除 try 块中分配的任何资源,以及运行任何即使在发生异常时也必须执行的代码

    finally 块用于清除 try 块中分配的任何资源,以及运行任何即使在发生异常时也必须执行的代码

  2. try catch finally语句块中存在return语句时的执行情况剖析

    2种场景 (1) try中有return,finally中没有return(注意会改变返回值的情形);(2) try中有return,finally中有return; 场景代码分析(idea亲测) 场 ...

  3. Java中的try、catch、finally块简单的解析

    package com.wangzhu; import java.util.HashMap; import java.util.Map; /** * 在try.catch.finally块中,若try ...

  4. finally块中的代码一定会执行吗?

    在Sun Tutorial中有这样一句话:The finally block always executes when the try block exits. This ensures that t ...

  5. [改善Java代码]不要在finally块中处理返回值

    在finally代码块中处理返回值,这是在面试题中经常出现的题目.但是在项目中绝对不能再finally代码块中出现return语句,这是因为这种处理方式非常容易产生"误解",会严重 ...

  6. try、catch、finally的使用分析---与 return 相关

    看了一篇文章,讲解的是关于java中关于try.catch.finally中一些问题 下面看一个例子(例1),来讲解java里面中try.catch.finally的处理流程   1 2 3 4 5 ...

  7. java中finally和return的执行顺序

    注意:return的位置... 从这几个例子中可以看到,如果try之前没有有条件的return,则try..catch..finally语句块中的语句都是顺序执行(如果try中或者catch中 有re ...

  8. C#中的yield return

    4.1 迭代器块 一个迭代器块(iterator block)是一个能够产生有序的值序列的块.迭代器块和普通语句块的区别就是其中出现的一个或多个yield语句. yield return语句产生迭代的 ...

  9. 一个问题:关于finally中return吞掉catch块中抛出的异常

    今天遇到一个感觉很神奇的问题,记录一下问题以及自己分析问题的思路. 预警:不知道怎么看java字节码的朋友可能需要先看一下如何阅读java字节码才能看懂后面的解释. 我有一段程序: public cl ...

随机推荐

  1. PHP错误报告级别及调整方法

    运行PHP脚本时,PHP解析器会尽其所能能报告它遇到的问题.在PHP中错误报告的处理行为,都是通过PHP的配置文件php.ini中有关的配置指令确定的.另外PHP的错误报告有很多种级别,可以根据不同的 ...

  2. jquery 当前页导航高亮显示

    <script type="text/javascript"> $(document).ready(function(){ var myNav = $("#n ...

  3. iOS开发——OC篇&消息传递机制(KVO/NOtification/Block/代理/Target-Action)

     iOS开发中消息传递机制(KVO/NOtification/Block/代理/Target-Action)   今晚看到了一篇好的文章,所以就搬过来了,方便自己以后学习 虽然这一期的主题是关于Fou ...

  4. java面试(毕业一年后准备换工作)

    还记得一年前的今天,在网上投简历,找工作,当时找的工作的工作地点都在成都,其实自己挺想去外面工作几年的,如果毕业后就在成都工作,今后基本不可能去外省了, 所以刚好上海的一家外包公司来成都理工校招,导员 ...

  5. [转载] $\mathrm{Jordan}$标准型的介绍

    本文转载自陈洪葛的博客$,$ 而实际上来自xida博客朝花夕拾$,$ 可惜该博客已经失效 $\mathrm{Jordan}$ 标准形定理是线性代数中的基本定理$,$ 专门为它写一篇长文好像有点多余$: ...

  6. 【转】vim 修改tab为四个空格

    原文网址:http://blog.sina.com.cn/s/blog_620ccfbf01010erz.html 为了vim更好的支持python写代码,修改tab默认4个空格有两种设置方法: 1. ...

  7. InstallShield: cannot extract icon with index 0错误解决方案

    在VS2012打包过程中,遇到这个错误,困扰我好几天,后来通过谷歌找到解决方案,如下: Expand the deploy solution (+) on the right panel (Solut ...

  8. C++注释和doxygen注释

    C++注释 C++的注释只有两种: 单行注释,以“//”开头: 段落注释,以“/*”开始,以“*/”结束. int value; // value是一个整型变量,这是一句单行注释 /* Test是一个 ...

  9. C# POST数据到指定页面,并跳转至该页面

    /// <summary> /// 跨页面POST数据 /// </summary> public class RemotePost : Dictionary<strin ...

  10. Perl时间处理函数

    官方网址:http://search.cpan.org/~stbey/Date-Calc-6.3/lib/Date/Calc.pod#___top use Date::Calc qw( Days_in ...