读书人

在编译级别1.4时jvm编译try/catch/fin

发布时间: 2013-03-19 17:22:05 作者: rapoo

在编译级别1.4时jvm编译try/catch/finally块的方式

? ? ? ? 先上一段很简单,且不考虑健壮性的源码:

import java.io.FileInputStream;import java.io.IOException;public class TryCatchFinallyTest {/** * @param args * @throws IOException  */public static void main(String[] args) throws IOException {FileInputStream fips = null;try {fips = new FileInputStream("hello.txt");fips.read();} catch (IOException e) {e.printStackTrace();} finally {fips.close();}}}

? ? ? ? ?然后上一段这段代码在eclipse编译级别为1.4、没有inline finally块时编译出的字节码:

// Compiled from TryCatchFinallyTest.java (version 1.2 : 46.0, super bit)public class TryCatchFinallyTest {  // Method descriptor #6 ()V  // Stack: 1, Locals: 1  public TryCatchFinallyTest();    0  aload_0 [this]    1  invokespecial java.lang.Object() [8]    4  return      Line numbers:        [pc: 0, line: 6]      Local variable table:        [pc: 0, pc: 5] local: this index: 0 type: TryCatchFinallyTest  // Method descriptor #15 ([Ljava/lang/String;)V  // Stack: 3, Locals: 5  public static void main(java.lang.String[] args) throws java.io.IOException;     0  aconst_null     1  astore_1 [fips]     2  new java.io.FileInputStream [19]     5  dup     6  ldc <String "hello.txt"> [21]     8  invokespecial java.io.FileInputStream(java.lang.String) [23]    11  astore_1 [fips]    12  aload_1 [fips]    13  invokevirtual java.io.FileInputStream.read() : int [26]    16  pop    17  goto 43    20  astore_2 [e]    21  aload_2 [e]    22  invokevirtual java.io.IOException.printStackTrace() : void [30]    25  goto 43    28  astore 4    30  jsr 36    33  aload 4    35  athrow    36  astore_3    37  aload_1 [fips]    38  invokevirtual java.io.FileInputStream.close() : void [33]    41  ret 3    43  jsr 36    46  return      Exception Table:        [pc: 2, pc: 17] -> 20 when : java.io.IOException        [pc: 2, pc: 25] -> 28 when : any        [pc: 43, pc: 46] -> 28 when : any      Line numbers:        ......      Local variable table:        [pc: 0, pc: 47] local: args index: 0 type: java.lang.String[]        [pc: 2, pc: 47] local: fips index: 1 type: java.io.FileInputStream        [pc: 21, pc: 25] local: e index: 2 type: java.io.IOException}

? ? ? ? ?2-17是try块代码;

? ? ? ? ? ?20-25是catch块代码;

? ? ? ? ? ?28-35是编译期生产的catch块之外的异常即any类型异常要执行的代码;

? ? ? ? ? ?36-41是finally块代码;

? ? ? ? ? ?43-46是编译期生成的字节码;

? ? ? ? ? ?其中偏移量17和25处都是goto 43,然后jsr到finally,即try和catch块都是到43;any类型中有一条指令jsr到finally块。

? ? ? ? 归纳总结下,try/catch/finally结构中:

? ? ? ? 1、try/catch块翻译成指令后最后一条字节码指令都是goto到一个编译出来的块A(43-46),A第一条指令(43)即jsr到finally块第一条指令,finally完就ret到A第二条指令即return(46)

? ? ? ? 2、any块,即catch之外的异常类型,也即any,是jvm自己构造了一个指令块B(28-35),先store下这种异常实例到局部变量表(28),然后jsr到finally块中(30),finally完就ret到B的第三条指令(33)执行,load出之前存储到局部变量表的异常实例,然后athrow(35)。

?

? ? ? ? JSR指令后边一般是:

? ? ? ? 1、load返回值然后return的指令(try/catch块,有返回值)

? ? ? ? 2、直接return(try/catch块,无返回值)

? ? ? ? 3、load出异常然后athrow(catch any)

?

读书人网 >编程

热点推荐