迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

如何解决Java中的 java.lang.NullPointerException 异常

作者:迹忆客 最近更新:2023/01/08 浏览次数:

什么是 NullPointerException ?

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

int x;
x = 10;

在本例中,变量 x 是一个 int,Java 将自动将其初始化为 0。 当我们在第二行分配值 10 时,那么值 10 将写入 x 引用的内存位置。

但是,当我们尝试声明引用类型时,会发生不同的事情。 看下面的代码:

public class Exception {
    public static void main(String[] args) {
        Integer num = null;
        num = new Integer(10);
    }
}

第一行声明了一个名为 num 的变量,但它实际上还没有包含原始值。相反,它包含一个指针(因为类型是 Integer,它是一个引用类型)。由于我们还没有说要指向什么,Java 将它设置为 null,这意味着“没有指向任何东西”。

在第二行中,new 关键字用于实例化(或创建)一个 Integer 类型的对象,并将指针变量 num 分配给该 Integer 对象。

NullPointerException (NPE) 发生在我们声明一个变量但未创建对象并将其分配给该变量之前尝试使用该变量的内容(称为取消引用)。所以我们指向的东西实际上并不存在。

取消引用通常发生在使用 .访问方法或字段,或使用 [ 索引数组。

如果我们在创建对象之前尝试取消引用 num,则会收到 NullPointerException 。在最微不足道的情况下,编译器会发现问题并让您知道“num 可能尚未初始化”,但有时我们可能会编写不直接创建对象的代码。

例如,我们可能有如下方法:

public void doSomething(SomeObject obj) {
   // 对 obj 做某些处理,假设 obj 不为空
   obj.myMethod();
}

在这种情况下,我们不是在创建对象 obj,而是假设它是在调用 doSomething() 方法之前创建的。 请注意,可以像这样调用该方法:

doSomething(null);

在这种情况下,obj 为 null,并且语句 obj.myMethod() 将抛出 NullPointerException 异常。

如果该方法打算像上述方法那样对传入的对象执行某些操作,则抛出 NullPointerException 是合适的,因为这是程序员造成的错误,程序员将需要该信息进行调试。

除了作为方法逻辑的结果抛出 NullPointerExceptions 之外,我们还可以通过在方法开头附近添加类似以下内容来检查方法参数的 null 值并显式抛出 NPE:

// 如果 obj 为 null,则抛出带有自定义错误消息的 NullPointerExceptions
Objects.requireNonNull(obj, "obj must not be null");

注意,在错误消息中清楚地说明哪个对象不能为空是有帮助的。 验证这一点的好处是 1) 我们可以返回自己更清晰的错误消息,以及 2) 对于我们知道的其余方法,除非重新分配 obj,否则它不为 null 并且可以安全地取消引用。

或者,可能存在方法的目的不仅仅是对传入的对象进行操作的情况,因此可以接受空参数。 在这种情况下,我们需要检查空参数并采取不同的操作。 我们还应该在注释中说明这一点。 例如,doSomething() 可以写成:

/**
  * @param obj ____ 的可选 foo。 可能为空,在这种情况下结果将是 ____
  */
public void doSomething(SomeObject obj) {
    if(obj == null) {
       // Do something
    } else {
       // Do something else
    }
}

最后,是如何使用 Stack Trace 查明异常和原因了。

现在 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.lang.NullPointerException 错误的。

public class Exception {
    public static void main(String[] args) {
        Integer num = null;
        num.hashCode();
    }
}

运行示例

运行上面的代码,将会报出如下的错误

java.lang.NullPointerException 错误

我们也可以点击上面的运行示例来在线查看效果。

在 main 方法内部的第一行,我们明确地将 Integer 引用 num 设置为 null。 这意味着我们有一个引用,但它没有指向任何对象。 之后,尝试通过调用一个方法来将引用视为指向一个对象。 这会导致 NullPointerException,因为在引用指向的位置没有要执行的代码。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Do you understand JavaScript closures?

发布时间:2025/02/21 浏览次数:108 分类:JavaScript

The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.

Do you know about the hidden traps in variables in JavaScript?

发布时间:2025/02/21 浏览次数:178 分类:JavaScript

Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av

How much do you know about the Prototype Chain?

发布时间:2025/02/21 浏览次数:150 分类:JavaScript

The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start

JavaScript POST

发布时间:2024/03/23 浏览次数:96 分类:JavaScript

本教程讲解如何在不使用 JavaScript 表单的情况下发送 POST 数据。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便