If I compile the following source code:
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. }
with Java-7 (either OpenJDK or Oracle) I get the following LineNumberTable:
line 3: 0
line 6: 30
line 8: 32
However, compiling the same source code with Java 8 (either OpenJDK or Oracle) I get another LineNumberTable:
line 3: 0
line 4: 16
line 6: 30
line 8: 32
Why does the LineNumberTable returned by Java 7 not include lines 4 and 5?
And why does the LineNumberTable returned by Java 8 not include line 5?
Well, it isn’t exactly specified, how many hints compilers should include. It’s always a trade-off between usefulness and resulting code size. In the worst case, you would have a several byte length information for each single-byte instruction. Also, certain language constructs may generate instructions spread over different byte code locations, whereas others do not not map to byte code instructions at all.
The strategy of previous javac
implementations was simple. Unlike Eclipse, it doesn’t generate line number information for expressions, but only for statements. So a single statement may span multiple source code lines but its entire code gets associated with the statement’s first line only.
Apparently, this strategy has been changed to make an exception to this rule when there are embedded method invocations. So for method invocations, there will be a line number information, but not for other expressions.
You may verify this by playing around with multi-line statements deliberately adding or removing nested invocations. E.g., the following code
static int test(int a, int b, int c, int d) {
return
a
+b
+c
+d;
}
will report only a single line number, the one bearing the return
keyword. Now change the code to
static int test(int a, int b, int c, int d) {
return
a
+b
+c+test(a,b,c,d)
+d;
}
and the line number table will have two entries, the one of the return
keyword and the one of the nested method invocation. You may move the invocation to a different line or even adding another invocation, e.g.
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);
}
and the line number table will support my guess about javac
’s new strategy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With