Java 编译程序时如何打印stacktrace?
这是一个非常简单的问题: 当您编译java程序时,它被转换为字节码,所以,.java或.class文件的每一行号都会丢失(我想是的,可能我错了…)。那么,当您打印堆栈跟踪时,它是如何获得调用堆栈中的所有类名和行号的呢?我想我可能遗漏了一些东西,但我找不到任何与此相关的东西 编译java程序时,它会转换为字节码 对 因此,.java或.class文件的每一行号都丢失了(我想是的,可能我错了…) 你错了。行号信息嵌入到.class文件中,除非以某种方式使用Java 编译程序时如何打印stacktrace?,java,compiler-construction,stack-trace,bytecode,Java,Compiler Construction,Stack Trace,Bytecode,这是一个非常简单的问题: 当您编译java程序时,它被转换为字节码,所以,.java或.class文件的每一行号都会丢失(我想是的,可能我错了…)。那么,当您打印堆栈跟踪时,它是如何获得调用堆栈中的所有类名和行号的呢?我想我可能遗漏了一些东西,但我找不到任何与此相关的东西 编译java程序时,它会转换为字节码 对 因此,.java或.class文件的每一行号都丢失了(我想是的,可能我错了…) 你错了。行号信息嵌入到.class文件中,除非以某种方式使用-g编译器选项 编译java程序时,它会转换
-g
编译器选项
编译java程序时,它会转换为字节码
对
因此,.java或.class文件的每一行号都丢失了(我想是的,可能我错了…)
你错了。除非以某种方式使用
-g
编译器选项,否则行号信息将嵌入到.class文件中。如果存在行号,则java编译器将创建字节码,并将调试
标志设置为true。这可以使用java-g
从Oracle的文档中:
-g
- 生成所有调试信息,包括局部变量。默认情况下,只生成行号和源文件信息
-g:none
- 不要生成任何调试信息
-仅生成某些类型的调试信息,由逗号分隔的关键字列表指定。有效关键字包括:-g:{关键字列表}
来源
- 源文件调试信息
行
- 行号调试信息
vars
- 局部变量调试信息
如果存在行号,那么java编译器将创建字节码,并将
debug
标志设置为true。这可以通过使用java-g
从Oracle的文档中:
-g
- 生成所有调试信息,包括局部变量。默认情况下,只生成行号和源文件信息
-g:none
- 不要生成任何调试信息
-仅生成某些类型的调试信息,由逗号分隔的关键字列表指定。有效关键字包括:-g:{关键字列表}
来源
- 源文件调试信息
行
- 行号调试信息
vars
- 局部变量调试信息
类名(以及变量名、方法名…)不会被删除。它们在字节码中。您甚至可以在.class文件上使用文本编辑器看到这一点。许多其他语言也是如此。人们很快发现,在原始可执行代码中加入“调试符号”是一件很有用的事情。即使没有文件名和行号(这些可以去掉),仍然可以得到类名和方法名(这些是实际运行程序所必需的,Java是很晚绑定的)。类名(以及变量名、方法名…)不会被擦除。它们在字节码中。你甚至可以在.class文件上使用文本编辑器看到这一点。这对于许多其他语言也是如此。人们很快发现,在原始可执行代码中加入“调试符号”是一件有用的事情。即使没有文件名和行号(这些可以剥离),你仍然会得到类名和方法名(这些是实际运行程序所需要的,Java是很晚绑定的)。字节码什么时候会成为汇编代码?我想我在这里有点困惑。@PabloMatíasGomez:定义“汇编代码”。字节码是JVM运行的编译输出。它可能会也可能不会进一步编译为实际的机器代码。“汇编”是一种人类可读的编程语言,非常接近二进制代码(字节码或机器代码)。@现在我明白了!当我说“汇编代码”时我指的是汇编程序,但当然,我错过了JVM直接运行字节码的部分。字节码什么时候会成为汇编代码?我想我有点困惑。@PabloMatíasGomez:定义“汇编代码”。字节码是JVM运行的编译输出。它可能会也可能不会进一步编译为实际的机器代码。“汇编”是一种人类可读的编程语言,非常接近二进制代码(字节码或机器代码)。@现在我明白了!当我说“汇编代码”时我的意思是类似汇编程序的东西,但当然,我错过了JVM直接运行字节码的部分。