Reputation: 173
Given the following method in Java in jdk6
public void test(){
Integer i;
try{
i = 9;
} catch (Exception ex){
//nothing
}
int something = 1; //Breakpoint here
}
When I stop at the break point I dont see a variable "i" on stack at all even though going step by step I see that is was assigned 9 in the try block.
public void test(){
Integer i = null;
try{
i = 9;
} catch (Exception ex){
//nothing
}
int something = 1; //Breakpoint here
}
Initializing the variable "i" to null I will see the i = 9 when I get to the breakpoint.
I am just wondering what happens under the hood. Does compiler not put i on the stack in the first case or does the cause stem from JVM behavior itself.
Upvotes: 4
Views: 62
Reputation: 13663
I'm assuming that "I dont see a variable "i" on stack at all" in your question means you don't see it in the stack frame in your debugger. (As opposed to on the JVM operand stack, which is a bytecode-level notion. It wouldn't be on the operand stack either, but for a different reason.)
Here's javap
(disassembles Java .class files) output for your method:
public void test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=1
0: bipush 9
2: invokestatic #8 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: goto 10
9: astore_2
10: iconst_1
11: istore_2
12: return
Exception table:
from to target type
0 6 9 Class java/lang/Exception
LineNumberTable:
line 27: 0
line 30: 6
line 28: 9
line 31: 10
line 32: 12
LocalVariableTable:
Start Length Slot Name Signature
10 0 2 ex Ljava/lang/Exception;
0 13 0 this LExample;
6 3 1 i Ljava/lang/Integer;
12 1 2 something I
When you set a breakpoint on the commented line (line 31 in my source file), you're setting a breakpoint at bytecode index 10 (based on the LineNumberTable
). The LocalVariableTable
shows i
only live from indices 6 through 9, hence why your debugger doesn't show it. Note that i
's storage location, local variable slot 1, is not overwritten in the method; some debuggers will take advantage of this to show the value even if the variable is no longer live. (If you use a bytecode optimizer/obfuscator/packer/etc, it may alter the bytecode to reuse local variable slots to make the bytecode smaller, harder to debug, or more compressible. Of course it will probably remove the debug information entirely at the same time.)
Upvotes: 1