有关堆栈跟踪中的行号的文档
有没有关于 Java 堆栈跟踪行号的明确文档?
打印堆栈跟踪时它们是如何“计算”的(其背后的逻辑,而不是实现)?
为了向您展示为什么我感到困惑,请使用以下代码片段:
public static void main(String[] args) {
String evilString = null;
System.out.println(new StringBuilder()
.append(evilString.toLowerCase()));
evilString.toUpperCase();
}
它给出: 线程“main”中的异常 java.lang.NullPointerException 在 be.company.training.ocjp6.App.main(App.java:28)
而以下代码段:
public static void main(String[] args) {
String evilString = null;
System.out.println(new StringBuilder()
.append("".toLowerCase()));
evilString.toUpperCase();
}
给出: 线程“main”中的异常 java.lang.NullPointerException 在 be.company.training.ocjp6.App.main(App.java:30)
所以我知道运行 StringBuilder
方法链使其被视为 1 行(StringBuilder 代码在我的编辑器中从第 28 行开始)。但是,如果错误发生在邪恶字符串.toUpperCase() 代码段中,我们将回到第 30 行的正轨。
我想知道,以便当我看到堆栈跟踪时,我可以确定错误发生在哪一行(链接方法) (多行)在我正在查看的代码中很常见)。
Is there any clear documentation on Java stack trace line numbers?
How are they "calculated" when printing a stack-trace (the logic behind it, not the implementaton)?
To show you why I'm confused, take the following code snippet:
public static void main(String[] args) {
String evilString = null;
System.out.println(new StringBuilder()
.append(evilString.toLowerCase()));
evilString.toUpperCase();
}
It gives:
Exception in thread "main" java.lang.NullPointerException
at be.company.training.ocjp6.App.main(App.java:28)
While the following piece of code:
public static void main(String[] args) {
String evilString = null;
System.out.println(new StringBuilder()
.append("".toLowerCase()));
evilString.toUpperCase();
}
Gives:
Exception in thread "main" java.lang.NullPointerException
at be.company.training.ocjp6.App.main(App.java:30)
So I understand that running the chain of StringBuilder
methods makes it being treated as 1 line (the StringBuilder code starts at line 28 in my editor). But if the error happens in the evilString.toUpperCase() snippet, we're back on track with line 30.
I want to know so that when I see a stacktrace, I can know for sure on what line the error happened (chaining methods (on multiple lines) is very common in the code I'm looking at).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 @kdgregory 指出的那样,这似乎取决于编译器。
这是我的 java -version:
使用此代码,我在每个堆栈跟踪的第 9 行上进行 NPE(与源中的物理行号匹配)
所以我使用 javap 进行了更深入的挖掘:
这是 main 的行号表,如下所示javap -l
(行号表显示源行:指令偏移
源第 9 行从偏移量 12 开始。
反汇编的 javap -c 显示以下内容:
我的猜测:
当在偏移量 13 处的 invokevirtual 处发生异常时,jvm 会在行号表中查找最近的先前条目并将其放入堆栈跟踪中。
Seems like this is compiler dependent as @kdgregory noted.
Here's my java -version:
With this code, I NPE on line 9 per the stack trace (which matches the physical line number in the source)
So I dug a little deeper using javap:
This is the line number table for main as shown by javap -l
(line number table shows source line: instruction-offset
source line 9 starts at offset 12.
javap -c to disassemble shows this:
my guess:
when the exception is hit at the invokevirtual at offset 13, the jvm looks up the closest prior entry in the line number table and puts that in the stack trace.
你确定 Java 中的
""
等于null
吗?我相信这就是你困惑的根源。您是否尝试过在第 30 行编写"".toUpperCase();
?are you sure that
""
equalsnull
in Java? I believe that this is the source of your confusion. have you tried writing"".toUpperCase();
on line 30?