LocalVariableTable缺少什么?

时间:2017-07-26 13:33:25

标签: java exception-handling bytecode

给出一个简单的try-catch-finally方法:

public void t() {
    try {
        f1();
    }catch(Exception e) {
        f2();
    }finally {
        f3();
    }
}

使用" javac -g",它被编译成:

public void t();
  descriptor: ()V
  flags: ACC_PUBLIC
  Code:
stack=1, locals=3, args_size=1
   0: aload_0
   1: invokespecial #15                 // Method f1:()V
   4: goto          26
   7: astore_1
   8: aload_0
   9: invokespecial #18                 // Method f2:()V
  12: aload_0
  13: invokespecial #21                 // Method f3:()V
  16: goto          30
  19: astore_2
  20: aload_0
  21: invokespecial #21                 // Method f3:()V
  24: aload_2
  25: athrow
  26: aload_0
  27: invokespecial #21                 // Method f3:()V
  30: return
Exception table:
   from    to  target type
       0     4     7   Class java/lang/Exception
       0    12    19   any
LineNumberTable:
  line 7: 0
  line 8: 4
  line 9: 8
  line 11: 12
  line 10: 19
  line 11: 20
  line 12: 24
  line 11: 26
  line 13: 30
LocalVariableTable:
  Start  Length  Slot  Name   Signature
      0      31     0  this   Lsample/Sample;
      8       4     1     e   Ljava/lang/Exception;
StackMapTable: number_of_entries = 4
  frame_type = 71 /* same_locals_1_stack_item */
    stack = [ class java/lang/Exception ]
  frame_type = 75 /* same_locals_1_stack_item */
    stack = [ class java/lang/Throwable ]
  frame_type = 6 /* same */
  frame_type = 3 /* same */

注意locals = 3,但LocalVariableTable中只有两个项目。字节码行19(astore_2)和24(aload_2)表示第三个局部变量确实存在。

问题是:什么是第三个局部变量,以及为什么在LocalVariableTable中错过了它?

1 个答案:

答案 0 :(得分:1)

第三个局部变量是finally块的实现细节。在你的try / catch抛出一个变量的情况下,它必须暂时存储异常,这样它才能在重新抛出之前调用f3(),这就是插槽2正在做的事情。