小编典典

JVM如何执行Try catch finally块

java

根据Java语言规范的第§14.20.2节

通过首先执行try块来执行带有finally块的try语句。然后有一个选择:

  • 如果try块的执行正常完成,则执行finally块,然后可以选择:
    • 如果finally块正常完成,则try语句正常完成。
    • 如果finally块由于原因S突然完成,则try语句由于原因S突然完成

如果我正确地解释了它,那么在执行try块之后最终会被调用,但是所有这些如何工作以及为什么得到输出,

public static int TestTryFinallyBlock()  
{
    int  i =0;
    try 
    {
        i= 10; //Perform some more operation
        return i;
    }       
    finally
    {
        i = 40; 
    }
}

public static void main( String[] args )
{
    int i1 = TestTryFinallyBlock(); //Here the output was 10 not 40
}

我想知道这件事如何产生输出10。

是在执行try块并遇到return语句时,输出值已经被压入堆栈,然后执行finally块

我知道先遇到return然后再运行finally块,因此输出为10,但是 jvm如何解释或jvm如何处理try或转换finally块?
那个jvm是使用GOTO节的跳转节去到final节还是堆栈已经维护了?


阅读 274

收藏
2020-11-26

共1个答案

小编典典

稍作搜索后,看到生成了什么字节码,我发现实际上似乎没有finally块,并且JVM也没有生成跳转或goto语句。
上面的代码翻译为 (如果我正确解释字节码,如果我错了,请更正我)

public static int TestTryFinallyBlock()  
{
  int returnValue; //A temporary return variable
  try
  {
     int  i = 0;     
     i = 10; 
     returnValue = i; 
     i = 40; 
     return returnValue;    
  }
  catch (RuntimeException e)
  {
       i = 40; //finally section code id copied here too
       throw e;
  }
}

注意: 如果'i'是对可变类对象的引用,并且对象的内容在finally块中更改,则这些更改也将反映在返回的值中。

2020-11-26