Why the LocalVariableTable length of JVM ByteCode is incorrect in try-catch statement?

56 views Asked by At

I write a simple code:

L11    public void sum2() {
L12        int a = 25;
L13        try {
L14            int b = 8;
L15            if (a > 20) {
L16                int k = a + b;
L17                System.out.println("k=" + k);
L18            }
L19        } catch (Exception e) {
L20            e.printStackTrace();
L21        }
L22    }

I think the scope of variable b must be in the try statement, which is line 15~18.

But actually, when i use javap generate bytecode :

      Exception table:
         from    to  target type
             3    41    44   Class java/lang/Exception
      LineNumberTable:
        line 12: 0
        line 14: 3
        line 15: 6
        line 16: 12
        line 17: 16
        line 21: 41
        line 19: 44
        line 20: 45
        line 22: 49
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           16      25     3     k   I
            6      35     2     b   I
           45       4     2     e   Ljava/lang/Exception;
            0      50     0  this   Lcom/buzz/asm/util/Sum;
            3      47     1     a   I
      StackMapTable: number_of_entries = 3
        frame_type = 252 /* append */
          offset_delta = 41
          locals = [ int ]
        frame_type = 66 /* same_locals_1_stack_item */
          stack = [ class java/lang/Exception ]
        frame_type = 4 /* same */

The scope of variable b is line 15~21? (start=6,end=41) ,Why?

Why the LocalVariableTable of JVM ByteCode is incorrect?

1

There are 1 answers

0
Jefflee0915 On

Here’s a breakdown of the LocalVariableTable for your method:

this is the reference to the current object, it’s always in slot 0 and is in scope for the entire method.

a is in slot 1 and is in scope from bytecode instruction 3 to instruction 50 (the entire method).

b is in slot 2 and is in scope from instruction 6 to instruction 41 (the try block and the following code).

k is in slot 3 and is in scope from instruction 16 to instruction 41 (inside the if statement in the try block).

e is in slot 2 and is in scope from instruction 45 to instruction 49 (the catch block).

The scope of a variable in Java is determined by where it is declared. In your code, the variable b is declared inside the try block, so its scope is limited to that block and any blocks nested within it.

The Start and Length values in the LocalVariableTable represent the range of bytecode instructions over which the variable is in scope. The Start value is the index of the first bytecode instruction where the variable is in scope, and the Length is the number of bytecode instructions for which the variable remains in scope.

In your case, b is in slot 2 and is in scope from bytecode instruction 6 to instruction 41. This range includes the entire try block and the following code, up to the start of the catch block. This is because the catch block is a separate scope, and b is not in scope there.

So, the scope of b is not just lines 15-18 in your source code, but rather it extends from its declaration to the end of the try block and includes any additional code up to the start of the catch block. This is consistent with Java’s scoping rules, where a variable is in scope from the point it is declared until the end of the block in which it is declared.