使用javac的-g选项可将调试信息包含在已编译的代码中。
如果在运行时调试,但没有源代码,则调试信息很有用。
缺省情况下,仅生成行号和源文件信息,即未指定-g选项。
指定-g还包括局部变量调试信息。我们可以在调试期间看到变量的真实名称。
我们还可以使用-g:[keyword list]来控制在编译期间应包含哪些调试信息,其中关键字列表是以下关键字的逗号分隔列表:
- source:源文件调试信息。
- lines:行号调试信息。
- vars:局部变量调试信息。
-g:none 不会生成任何调试信息。
性能上有区别吗?
调试信息仅是元信息。
它增加了类文件的大小,从而增加了加载时间。
在未经调试的执行过程中,此信息将被完全忽略。这意味着,无论源是否使用调试信息进行编译,性能都没有差异。
例子
让我们使用javac编译该类,然后使用javap工具检查类文件中的调试信息:
public class Test {
private String myStr;
public Test(String s) {
this.myStr = s;
}
public void print() {
System.out.println(myStr);
}
public static void main(String[] args) {
Test test = new Test("test");
test.print();
}
}
不带-g选项进行编译,将不包含任何变量名:
D:\examples>javac Test.java
D:\examples>javap -l Test
Compiled from "Test.java"
public class Test {
public Test(java.lang.String);
LineNumberTable:
line 5: 0
line 6: 4
line 7: 9
public void print();
LineNumberTable:
line 10: 0
line 11: 10
public static void main(java.lang.String[]);
LineNumberTable:
line 14: 0
line 15: 10
line 16: 14
}
使用-g选项进行编译,将包括所有调试信息。注意变量名表:
D:\examples>javac -g Test.java
D:\examples>javap -l Test
Compiled from "Test.java"
public class Test {
public Test(java.lang.String);
LineNumberTable:
line 5: 0
line 6: 4
line 7: 9
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this LTest;
0 10 1 s Ljava/lang/String;
public void print();
LineNumberTable:
line 10: 0
line 11: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this LTest;
public static void main(java.lang.String[]);
LineNumberTable:
line 14: 0
line 15: 10
line 16: 14
LocalVariableTable:
Start Length Slot Name Signature
0 15 0 args [Ljava/lang/String;
10 5 1 test LTest;
}
没有任何调试信息的编译
D:\examples>javac -g:none Test.java
D:\examples>javap -l Test
public class Test {
public Test(java.lang.String);
public void print();
public static void main(java.lang.String[]);
}
仅使用变量名进行编译
D:\examples>javac -g:vars Test.java
D:\examples>javap -l Test
public class Test {
public Test(java.lang.String);
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this LTest;
0 10 1 s Ljava/lang/String;
public void print();
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this LTest;
public static void main(java.lang.String[]);
LocalVariableTable:
Start Length Slot Name Signature
0 15 0 args [Ljava/lang/String;
10 5 1 test LTest;
}
用行号和变量名编译:
D:\examples>javac -g:lines,vars Test.java
D:\examples>javap -l Test
public class Test {
public Test(java.lang.String);
LineNumberTable:
line 5: 0
line 6: 4
line 7: 9
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this LTest;
0 10 1 s Ljava/lang/String;
public void print();
LineNumberTable:
line 10: 0
line 11: 10
LocalVariableTable:
Start Length Slot Name Signature
0 11 0 this LTest;
public static void main(java.lang.String[]);
LineNumberTable:
line 14: 0
line 15: 10
line 16: 14
LocalVariableTable:
Start Length Slot Name Signature
0 15 0 args [Ljava/lang/String;
10 5 1 test LTest;
}
注意
选项-g不包含方法参数的名称,为此,我们需要使用javac的-parameters选项。