java - JVM 如何知道何时抛出 NullPointerException

标签 java nullpointerexception compiler-construction jvm

Java 虚拟机如何知道何时抛出 NullPointerException?如果对象为空,它是否会在我调用对象的每个方法之前检查它是否必须抛出 NullPointerException?如果是这样,这不是很慢吗?

最佳答案

JVM 可以使用两种方法来“检测”空值。

  • JVM 可以在使用引用之前显式测试引用的值。这代表了开销,但 JIT 编译器可以优化掉一些空测试。例如:

    1. this 的方法调用不能产生 NPE。
    2. 如果 p 不是 volatile 而你这样写:

      if (p != null) { p.something(); }
      

      那么,就不需要 p.something() 中隐含的 null 检查。

    3. 如果 p 不是 volatile 而你这样写:

      p.something();
      p.somethingElse();
      

      然后不需要第二个隐含的 null 检查。

    还值得注意的是,空测试可能对具有深度管道的 CPU 的性能影响为零。这将取决于本地化的内存访问模式,以及编译器/硬件是否能够安排测试指令与(比如)内存提取或存储重叠。

  • JVM 可以使用虚拟内存硬件实现 null 检查。 JVM 将其虚拟地址空间中的第 0 页映射到一个不可读 + 不可写的页面。由于 null 表示为零,因此当 Java 代码尝试取消引用 null 时,这将尝试访问不可寻址的页面,并导致操作系统发出“段错误”信号到 JVM。 JVM 的段错误信号处理程序可以捕捉到这一点,找出代码正在执行的位置,然后在适当线程的堆栈上创建和抛出一个 NPE。

    这很复杂而且相当昂贵。但是,只要 NPE 在应用程序中很少发生,费用就无关紧要。

关于java - JVM 如何知道何时抛出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36955433/

相关文章:

java - 如何在 android WebView 中定位类名?

java - 使用 TestRig 时 ANTLR 解析有效,但使用 Java 解析时失败

java - JTextArea 过滤器和/或时间输入 (00 :00:00) Java

空对象引用上的 java.lang.String.compareToIgnoreCase(java.lang.String)'

.net - VB.NET 语言和什么都没有 : why is it the way it is?

c++ - 编译器何时内联 C++ 代码?

java - 在 Java 中编译时如何包含现有代码/类文件

java - @AttributeOverride 不起作用

java - 线程中出现异常 "AWT-EventQueue-0"java.lang.NullPointerException JInternalFrame 关闭方法

java - 将 blob 转换为图像流并将其分配给 jLabel