英文:
Why is NPE not reported on correct line
问题
运行以下代码:
public class NPESample {
  String value;
  public static void main(String[] args) {
    NPESample npeSample = null;
    "foo"
        .replaceAll(
            "f",
            npeSample.value);
  }
}
将会得到:
Exception in thread "main" java.lang.NullPointerException
	at NPESample.main(NPESample.java:9)
报告的行数 (7) 是 "foo" 这一行,而不是实际发生 NPE 的行数 (10) npeSample.value。
为什么会这样?当我调试代码时,被报告的行数与代码中实际发生问题的行数不一致,这让我感到困惑。
要复现这个问题,运行以下代码:
cat > ./NPESample.java <<DELIM
public class NPESample {
  String value;
  public static void main(String[] args) {
    NPESample npeSample = null;
    "foo"
        .replaceAll(
            "f",
            npeSample.value);
  }
}
DELIM
javac NPESample.java
java NPESample
输出结果为:
Exception in thread "main" java.lang.NullPointerException
	at NPESample.main(NPESample.java:7)
javac -version
javac 13.0.1
java -version
openjdk version "13.0.1" 2019-10-15
OpenJDK Runtime Environment (build 13.0.1+9)
OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing)
英文:
Running the following:
public class NPESample {
  String value;
  public static void main(String[] args) {
    NPESample npeSample = null;
    "foo"
        .replaceAll(
            "f",
            npeSample.value);
  }
}
Will give:
Exception in thread "main" java.lang.NullPointerException
	at NPESample.main(NPESample.java:9)
Reported line (7) is the line "foo" and not the actual line where NPE happens (10) npeSample.value.
Why is this? I was caught by surprise when debugging code and thrown off by the "wrong" reported line number in the code.
To reproduce run this:
cat > ./NPESample.java <<DELIM
public class NPESample {
  String value;
  public static void main(String[] args) {
    NPESample npeSample = null;
    "foo"
        .replaceAll(
            "f",
            npeSample.value);
  }
}
DELIM
javac NPESample.java
java NPESample
output is:
Exception in thread "main" java.lang.NullPointerException
	at NPESample.main(NPESample.java:7)
javac -version
javac 13.0.1
java -version
openjdk version "13.0.1" 2019-10-15
OpenJDK Runtime Environment (build 13.0.1+9)
OpenJDK 64-Bit Server VM (build 13.0.1+9, mixed mode, sharing)
答案1
得分: 2
这在我看来并不像是一个 bug。具体来说,它似乎允许映射不必是一对一的,正如规范所述:
也就是说,LineNumberTable 属性可以共同表示源文件的某一行,并且不一定与源代码行一一对应。
甚至 JDK-15 报告了错误的行:
无法读取字段“value”,因为“npeSample”为空
位于第 9 行。
英文:
This does not look like a bug, to me. Specifically, it seems that the mapping is freely allowed not be one-one, as the SPEC says:
> That is, LineNumberTable attributes may together represent a given line of a source file, and need not be one-to-one with source lines.
Even JDK-15 reports the wrong line:
> Cannot read field "value" because "npeSample" is null
on line 9.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论