微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 堆栈跟踪中行号的文档

有没有关于 Java堆栈跟踪行号的明确文档?
当打印堆栈跟踪(后面的逻辑,而不是实现)时,他们如何“计算”?

显示为什么我感到困惑,请采取以下代码段:

public static void main(String[] args) {
        String evilString = null;
        System.out.println(new StringBuilder()
                .append(evilString.toLowerCase()));
        evilString.toupperCase();
    }

它给:
线程中的异常“main”java.lang.NullPointerException
at.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
at.company.training.ocjp6.App.main(App.java:30)

所以我明白,运行StringBuilder方法链接使它被视为1行(StringBuilder代码从我的编辑器的第28行开始).但是如果在evilString.toupperCase()代码片段中发生错误,那么我们将以第30行为准.

我想知道,当我看到一个堆栈跟踪,我可以知道错误发生了什么行(链接方法(多行)在我正在看的代码中很常见).

解决方法

像这样,似乎是编译器依赖于@kdgregory指出.

这是我的java -version:

java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-10M3527)
Java HotSpot(TM) Client VM (build 20.4-b02-402,mixed mode)

有了这个代码,我的NPE在第9行每堆栈跟踪(与源中的物理行号相匹配)

public static void main(String[] args) { 
    String evilString = null;
    System.out.println(new StringBuilder()
        .append(
                evilString.toLowerCase()));  // <--- NPE here (line 9)
}

所以我用javap挖出一点点:

这是主要的行号表,如javap -l所示

(行号表显示源行:指令偏移量

public static void main(java.lang.String[]);
LineNumberTable: 
line 6: 0
line 7: 2
line 9: 12
line 8: 16
line 7: 19
line 10: 22

源极线9从偏移12开始.

javap -c来反汇编显示

public static void main(java.lang.String[]);
Code:
0:  aconst_null
1:  astore_1
2:  getstatic   #16; //Field java/lang/System.out:Ljava/io/PrintStream;
5:  new #22; //class java/lang/StringBuilder
8:  dup
9:  invokespecial   #24; //Method java/lang/StringBuilder."<init>":()V
12: aload_1                                                    <--- closest line in the line number table
13: invokevirtual   #25; //Method java/lang/String.toLowerCase:()Ljava/lang/String;       <--- NPE here
16: invokevirtual   #31; //Method java/lang/StringBuilder.append:      (Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual   #35; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
22: return

我猜:当在偏移量13处的invokevirtual处遇到异常时,jvm将查找行号表中最接近的先前条目,并将其放在堆栈跟踪中.

原文地址:https://www.jb51.cc/java/125609.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐