java - 什么是 NullPointerException,我该如何解决?

标签 java nullpointerexception

这个问题的答案是community effort .编辑现有答案以改进这篇文章。它目前不接受新的答案或互动。








什么是空指针异常 ( java.lang.NullPointerException ) 以及导致它们的原因?

可以使用哪些方法/工具来确定原因,以便阻止异常导致程序过早终止?

最佳答案

当您声明一个引用变量(即一个对象)时,您实际上是在创建一个指向对象的指针。考虑以下代码,其中声明了一个原始类型的变量 int :

int x;
x = 10;
在本例中,变量 xint Java 会将其初始化为 0为你。当您分配 10 的值时在第二行,您的值 10被写入 x 所指的内存位置.
但是,当您尝试声明引用类型时,会发生一些不同的事情。取以下代码:
Integer num;
num = new Integer(10);
第一行声明了一个名为 num 的变量,但它实际上并不包含原始值。相反,它包含一个指针(因为类型是 Integer,这是一个引用类型)。由于您还没有说要指向什么,Java 将其设置为 null , 意思是“ 我没有指向 ”。
在第二行中,new关键字用于实例化(或创建)类型 Integer 的对象,以及指针变量 num分配给 Integer目的。NullPointerException (NPE) 当您声明一个变量但未创建对象并将其分配给该变量,然后再尝试使用该变量的内容(称为取消引用)时,就会发生 (NPE)。所以你指的是一些实际上并不存在的东西。
取消引用通常发生在使用 . 时访问方法或字段,或使用 [索引一个数组。
如果您尝试取消引用 num在创建对象之前,您会得到一个 NullPointerException .在最琐碎的情况下,编译器会发现问题并让您知道“num may not have been initialized”,但有时您可能会编写不直接创建对象的代码。
例如,您可能有如下方法:
public void doSomething(SomeObject obj) {
   // Do something to obj, assumes obj is not null
   obj.myMethod();
}
在这种情况下,您不是在创建对象 obj ,而是假设它是在 doSomething() 之前创建的方法被调用。请注意,可以像这样调用该方法:
doSomething(null);
在这种情况下,objnull ,以及声明 obj.myMethod()会抛出 NullPointerException .
如果该方法打算像上述方法那样对传入的对象做一些事情,则抛出 NullPointerException 是合适的。因为这是程序员错误,程序员将需要该信息进行调试。
除了NullPointerException s 作为方法逻辑的结果抛出,您还可以检查 null 的方法参数值并通过在方法的开头附近添加类似以下内容来显式抛出 NPE:
// Throws an NPE with a custom error message if obj is null
Objects.requireNonNull(obj, "obj must not be null");
请注意,在错误消息中明确说明哪个对象不能是 null 会很有帮助。 .验证这一点的优点是 1) 您可以返回自己的更清晰的错误消息,2) 对于您知道的其余方法,除非 obj被重新分配,它不为空并且可以安全地取消引用。
或者,可能存在方法的目的不仅仅是对传入的对象进行操作的情况,因此空参数可能是可以接受的。在这种情况下,您需要检查 空参数 并且行为不同。您还应该在文档中解释这一点。例如,doSomething()可以写成:
/**
  * @param obj An optional foo for ____. May be null, in which case
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj == null) {
       // Do something
    } else {
       // Do something else
    }
}
最后,How to pinpoint the exception & cause using Stack Trace

What methods/tools can be used to determine the cause so that you stop the exception from causing the program to terminate prematurely?


带有发现错误的声纳可以检测 NPE。
Can sonar catch null pointer exceptions caused by JVM Dynamically
现在 Java 14 增加了一个新的语言特性来显示 NullPointerException 的根本原因。自 2006 年以来,此语言功能已成为 SAP 商业 JVM 的一部分。
在 Java 14 中,以下是示例 NullPointerException 异常消息:

in thread "main" java.lang.NullPointerException: Cannot invoke "java.util.List.size()" because "list" is null

关于java - 什么是 NullPointerException,我该如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40255863/

相关文章:

java - 将 Cron 作业与 Appengine Endpoints API 结合使用

java - 黑莓列表字段 : Maintaining row focus during an update

java - Android,Glide图像加载库: NullPointerException, ProviderInfo

java - 什么是NullPointerException,我该如何解决?

第 X 行的 Android 搜索建议光标返回异常

java - 什么是 Java NullPointerException?

检查数字是否满意的 Java 程序会产生不可能的输出

java - Java中的抽象类正在运行,显然需要无参数构造函数,返回NaN?

JavaFX - 尝试将功能添加到启动功能时出错

Java-SWT : How to update Label?