Compiler construction Java-don';在调试过程中,如果没有对变量进行初始化,则无法看到该变量
给定jdk6中Java中的以下方法Compiler construction Java-don';在调试过程中,如果没有对变量进行初始化,则无法看到该变量,compiler-construction,jvm,stack,Compiler Construction,Jvm,Stack,给定jdk6中Java中的以下方法 public void test(){ Integer i; try{ i = 9; } catch (Exception ex){ //nothing } int something = 1; //Breakpoint here } 当我停在断点时,我根本看不到堆栈上的变量“I”,即使一步一步地走,我看到try块中分配了9 public void test(){ Integer i = null; try{ i = 9; } catch
public void test(){
Integer i;
try{
i = 9;
} catch (Exception ex){
//nothing
}
int something = 1; //Breakpoint here
}
当我停在断点时,我根本看不到堆栈上的变量“I”,即使一步一步地走,我看到try块中分配了9
public void test(){
Integer i = null;
try{
i = 9;
} catch (Exception ex){
//nothing
}
int something = 1; //Breakpoint here
}
将变量“i”初始化为null,当到达断点时,我将看到i=9
我只是想知道引擎盖下发生了什么。编译器在第一种情况下是否没有将i放在堆栈上,或者原因是否来自JVM行为本身。我假设您的问题中的“我根本没有在堆栈上看到变量”i“意味着您在调试器的堆栈框架中看不到它。(与JVM操作数堆栈相反,JVM操作数堆栈是字节码级别的概念。它也不在操作数堆栈上,但原因不同。)
下面是方法的javap
(反汇编Java.class文件)输出:
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
在注释行(我的源文件中的第31行)上设置断点时,就是在字节码索引10处设置断点(基于LineNumberTable
)。LocalVariableTable
只显示从索引6到9的i
活动,因此调试器不显示它。注意,i
的存储位置,局部变量插槽1,在方法中没有被覆盖;即使变量不再有效,一些调试器也会利用这一点来显示值。(如果使用字节码优化器/模糊器/打包器等,它可能会更改字节码以重用局部变量槽,从而使字节码更小、更难调试或更可压缩。当然,它可能会同时完全删除调试信息。)