Java 行号表 : Entry explanation

标签 java class bytecode

如果我反汇编我的类文件,我会得到以下形式的 LineNumberTables

  LineNumberTable:
    line 204: 0
    line 205: 9
    line 208: 57
    line 209: 63
    line 210: 72
    line 211: 75
    line 212: 78
    line 213: 87
    line 216: 90
    line 218: 118
    line 221: 126
    line 222: 131
    line 223: 138
    line 224: 143
    line 227: 150
    line 230: 157
    line 231: 160
    line 232: 170
    line 235: 194
    line 237: 228
    line 240: 249
    line 241: 259
    line 243: 266
    line 245: 269
    line 246: 292
    line 248: 295
    line 249: 301
    line 250: 308
    line 251: 315
    line 252: 322
    line 253: 329

我知道这些表包含调试信息,并且第一个条目是类文件中的某种位置,而第二个条目是源代码中的某个位置。我想知道:

  1. 源代码行号是相对的还是绝对的?如果我绝对地解释它们,有些指向多行注释的中间,这似乎很奇怪。

  2. 同一源代码的两种不同编译仅在一个字节上有所不同:条目“第 216: 90”被“第 215: 90 行”替换。我试图找出造成这种情况的原因。有什么想法吗?

最佳答案

将常识应用于您正在阅读的内容。当您正确阅读规范时,即存储在 LineNumberTable 属性数组中的第一个数字是字节码偏移量,第二个数字是行号,这并不意味着您使用的反汇编程序将也按该顺序打印它们。

有两个指标表明订单已被调换

  1. 第一个数字之前打印有“Line”一词,表明第一个数字是行号
  2. 第一个数字的范围是 204 到 253,这对于类声明中某个方法的源代码行来说是合理的,而第二个数字的范围是从 0329 ,这对于方法内从零开始的字节码偏移量来说是合理的。

    相比之下,方法的行号不太可能以零开头,因为源代码通常以 packageimport 声明开头。如果方法代码的前 203 个字节没有关联的源代码行,这也是不寻常的(尽管这并非不可能)。

这两个指标加起来都相当强劲。那么,观察到的变化是相当合理的。显然,生成的代码没有改变。但由于没有关于行号和生成的代码如何关联的标准,因此可能会存在细微的差异,具体取决于编译器版本,例如当一个表达式跨越多行,但只生成一条指令时,或者当编译器试图避免过多的行号表时。

例如代码

foo(
);

仅生成一条指令(如果foo()static),并且未定义两行中的哪一行与该指令关联。当它是一个实例方法时,它将由两条指令组成,但将它们表示为不同的行号是有争议的,因为在调试期间介入它们之间没有多大帮助。但这是编译器的决定。还带有

foo(
    null,
    1,
    true
);

将每个常量参数插入堆栈需要指令序列中的一个字节,而将不同的行号与每条指令相关联则每条指令需要另外四个字节。由于推送这些常量不太可能失败,因此跟踪它们没有什么意义,编译器可能决定将整个序列与调用指令的唯一行号相关联。由于此决定取决于实际的编译器,甚至可能取决于其当前配置,因此重新编译可能会更改关联。

另一个区别是编译器如何处理合成方法,例如桥接方法和内部类访问器。到目前为止,我已经看到,它们仅与零相关联,与周围类声明的开头以及它们委托(delegate)的实际目标成员的开头相关联。

关于Java 行号表 : Entry explanation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41104416/

相关文章:

java - 如何将字符串转换回字节以便用 Java 写入文件?

c++ - 如何通过类型和非类型模板参数重载模板类?

python 无法识别我的函数

python - 将 Python 类对象编译到列表中

java - 如果JVM生成机器代码,那么代码文件在哪里?

java - 给出意外匹配的正则表达式

Java将标准String转换为CP1250,每个字符只有一个字节

java - Drawrect 不工作(Java)

java - 是否有可能追踪到哪个表达式导致了 NPE?

java - 比较一个简单循环的 java 字节码?