Java 虚拟机如何知道何时抛出 NullPointerException?如果对象为空,它是否会在我调用对象的每个方法之前检查它是否必须抛出 NullPointerException?如果是这样,这不是很慢吗?
最佳答案
JVM 可以使用两种方法来“检测”空值。
JVM 可以在使用引用之前显式测试引用的值。这代表了开销,但 JIT 编译器可以优化掉一些空测试。例如:
- 对
this
的方法调用不能产生 NPE。 如果
p
不是 volatile 而你这样写:if (p != null) { p.something(); }
那么,就不需要
p.something()
中隐含的 null 检查。如果
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/