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)发生在您声明一个变量但没有创建对象并将其分配给变量之前尝试使用变量的内容(称为取消引用)。所以你指向的东西实际上并不存在。
使用 . 时通常会发生取消引用。访问方法或字段,或使用 [索引一个数组。
如果您尝试取消引用 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/60591676/

相关文章:

Java Applet getImage 给出空指针异常

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

java - Android 开发者网站上的 Java 规范 equals() 方法

java - Java 中 Redis 的监听器

java - map 缩减算法

java - Spark - 在字符串匹配后提取行并将其保存在 ArrayList 中

java - 合并排序代码抛出 NullPointerException

java - 服务层在 spring 应用程序中绑定(bind)到 DB 技术

java - JAAS 表单例份验证在 Jboss 中总是失败

java - Java 左子树中最右边的节点