javap 是否缺少一些行号?
Is javap missing some line numbers?
如果我编译如下源代码:
1. public class Example {
2. public boolean foo(boolean a, boolean b, char ch) {
3. if (a && Character.isLetter(ch)
4. || b && Character.isDigit(ch)
5. || !a && !b) {
6. return true;
7. }
8. return false;
9. }
10. }
与 Java-7(OpenJDK 或 Oracle)我得到以下 LineNumberTable:
line 3: 0
line 6: 30
line 8: 32
但是,使用 Java8(OpenJDK 或 Oracle)编译相同的源代码我得到另一个 LineNumberTable:
line 3: 0
line 4: 16
line 6: 30
line 8: 32
为什么Java7返回的LineNumberTable不包括第4行和第5行?
为什么Java8返回的LineNumberTable不包含第5行?
好吧,并没有明确规定,编译器应该包含多少提示。有用性和生成的代码大小之间始终存在 trade-off。在最坏的情况下,每个 single-byte 指令都会有几个字节的长度信息。此外,某些语言结构可能会生成分布在不同字节码位置的指令,而其他结构则根本不会映射到字节码指令。
以前 javac
实施的策略很简单。与 Eclipse 不同的是,它不会为 expressions 生成行号信息,而只会为 statements 生成行号信息。因此,单个语句可能跨越多个源代码行,但其整个代码仅与语句的第一行相关联。
显然,此策略已更改为在存在嵌入式方法调用时对该规则进行例外处理。所以对于方法调用,会有行号信息,但对于其他表达式则没有。
您可以通过故意添加或删除嵌套调用的 multi-line 语句来验证这一点。例如,下面的代码
static int test(int a, int b, int c, int d) {
return
a
+b
+c
+d;
}
将只报告一个行号,即带有 return
关键字的行号。现在将代码更改为
static int test(int a, int b, int c, int d) {
return
a
+b
+c+test(a,b,c,d)
+d;
}
和行号 table 将有两个条目,一个是 return
关键字,另一个是嵌套方法调用。您可以将调用移动到不同的行,甚至添加另一个调用,例如
static int test(int a, int b, int c, int d) {
return
a
+b+test(a,b,c,d)
+c
+d+test(a,b,c,d);
}
和行号table将支持我对javac
的新策略的猜测。
如果我编译如下源代码:
1. public class Example {
2. public boolean foo(boolean a, boolean b, char ch) {
3. if (a && Character.isLetter(ch)
4. || b && Character.isDigit(ch)
5. || !a && !b) {
6. return true;
7. }
8. return false;
9. }
10. }
与 Java-7(OpenJDK 或 Oracle)我得到以下 LineNumberTable:
line 3: 0
line 6: 30
line 8: 32
但是,使用 Java8(OpenJDK 或 Oracle)编译相同的源代码我得到另一个 LineNumberTable:
line 3: 0
line 4: 16
line 6: 30
line 8: 32
为什么Java7返回的LineNumberTable不包括第4行和第5行?
为什么Java8返回的LineNumberTable不包含第5行?
好吧,并没有明确规定,编译器应该包含多少提示。有用性和生成的代码大小之间始终存在 trade-off。在最坏的情况下,每个 single-byte 指令都会有几个字节的长度信息。此外,某些语言结构可能会生成分布在不同字节码位置的指令,而其他结构则根本不会映射到字节码指令。
以前 javac
实施的策略很简单。与 Eclipse 不同的是,它不会为 expressions 生成行号信息,而只会为 statements 生成行号信息。因此,单个语句可能跨越多个源代码行,但其整个代码仅与语句的第一行相关联。
显然,此策略已更改为在存在嵌入式方法调用时对该规则进行例外处理。所以对于方法调用,会有行号信息,但对于其他表达式则没有。
您可以通过故意添加或删除嵌套调用的 multi-line 语句来验证这一点。例如,下面的代码
static int test(int a, int b, int c, int d) {
return
a
+b
+c
+d;
}
将只报告一个行号,即带有 return
关键字的行号。现在将代码更改为
static int test(int a, int b, int c, int d) {
return
a
+b
+c+test(a,b,c,d)
+d;
}
和行号 table 将有两个条目,一个是 return
关键字,另一个是嵌套方法调用。您可以将调用移动到不同的行,甚至添加另一个调用,例如
static int test(int a, int b, int c, int d) {
return
a
+b+test(a,b,c,d)
+c
+d+test(a,b,c,d);
}
和行号table将支持我对javac
的新策略的猜测。