如果使用调试信息编译的话,我如何确定任何Java .class文件?
如何准确判断使用了-g {source | lines | vars}选项?
答案 0 :(得分:43)
如果你在命令行上,那么javap -l将显示LineNumberTable和LocalVariableTable(如果存在):
peregrino:$ javac -d bin -g:none src/Relation.java
peregrino:$ javap -classpath bin -l Relation
public class Relation extends java.lang.Object{
public Relation();
peregrino:$ javac -d bin -g:lines src/Relation.java
peregrino:$ javap -classpath bin -l Relation
public class Relation extends java.lang.Object{
public Relation();
LineNumberTable:
line 1: 0
line 33: 4
peregrino:$ javac -d bin -g:vars src/Relation.java
peregrino:$ javap -classpath bin -l Relation
public class Relation extends java.lang.Object{
public Relation();
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LRelation;
如果出现在反编译的开头, javap -c
将显示源文件:
peregrino:$ javac -d bin -g:none src/Relation.java
peregrino:$ javap -classpath bin -l -c Relation | head
public class Relation extends java.lang.Object{
...
peregrino:$ javac -d bin -g:source src/Relation.java
peregrino:$ javap -classpath bin -l -c Relation | head
Compiled from "Relation.java"
public class Relation extends java.lang.Object{
...
以编程方式,我会查看ASM,而不是编写另一个字节码阅读器。
答案 1 :(得分:2)
您必须检查类文件中的Code
structure并查找LineNumberTable
和LocalVariableTable
属性。
ASM或Apache Commons BCEL(字节代码工程库)等工具将有助于:https://commons.apache.org/proper/commons-bcel/apidocs/index.html?org/apache/bcel/classfile/LineNumberTable.html
答案 2 :(得分:0)
基于以上两个答案(Aaron Digulla和Pete Kirkham),您可以直接使用javap -v
检查jarfile或classfile。我发现这比使用类路径要简单一些。 jarfile大小写时,!
需使用单引号。
javap -v 'jar:file:///Absolute/Path/To/JarFile.jar!/package/name/using/slashes/ClassName.class' | grep "\(Compiled from\|LineNumberTable\|LocalVariableTable\)" | head
或(不需要绝对路径来检查类文件)
javap -v Path/To/ClassName.class | grep "\(Compiled from\|LineNumberTable\|LocalVariableTable\)" | head
如果结果不清楚或格式更改,请用管道输送到less
而不是grep
,然后进行查看。