什么是 NullPointerException,我该如何解决? [英] What is a NullPointerException, and how do I fix it?

查看:104
本文介绍了什么是 NullPointerException,我该如何解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

解决方案

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

int x;x = 10;

在这个例子中,变量 x 是一个 int,Java 会为你将它初始化为 0.当您在第二行分配 10 的值时,您的 10 值将写入 x 引用的内存位置.

但是,当您尝试声明一个引用类型时,会发生一些不同的事情.取以下代码:

整数编号;num = 新整数(10);

第一行声明了一个名为 num 的变量,但它实际上并不包含原始值.相反,它包含一个指针(因为类型是 Integer 这是一个引用类型).由于您还没有说要指向什么,Java 将其设置为 null,这意味着我指向 nothing".

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

NullPointerException (NPE) 当您声明一个变量但未创建对象并在尝试使用变量的内容(称为 取消引用).所以你指向的东西实际上并不存在.

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

如果您尝试在创建对象之前取消引用 num ,您会得到 NullPointerException.在最琐碎的情况下,编译器会发现问题并让您知道num 可能尚未初始化",但有时您可能会编写不直接创建对象的代码.

例如,您可能有如下方法:

public void doSomething(SomeObject obj) {//对 obj 做一些事情,假设 obj 不为 nullobj.myMethod();}

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

doSomething(null);

在这种情况下,objnull,并且语句 obj.myMethod() 将抛出一个 NullPointerException>.

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

除了作为方法逻辑的结果抛出的 NullPointerException 之外,您还可以检查 null 值的方法参数并通过添加类似的东西显式抛出 NPE在方法的开头附近跟随:

//如果 obj 为 null,则抛出带有自定义错误消息的 NPEObjects.requireNonNull(obj, obj 不能为 null");

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

或者,在某些情况下,方法的目的不仅仅是对传入的对象进行操作,因此空参数可能是可以接受的.在这种情况下,您需要检查 null 参数 并采取不同的行为.您还应该在文档中解释这一点.例如,doSomething() 可以写成:

/*** @param obj 一个可选的 foo 用于____.可能为空,在这种情况下* 结果将是____.*/公共无效doSomething(SomeObject obj){如果(对象 == 空){//做点什么} 别的 {//做其他事情}}

最后,如何查明异常&使用堆栈跟踪的原因

<块引用>

可以用什么方法/工具来确定原因,让你停止导致程序过早终止的异常?

带有发现错误的声纳可以检测 NPE.声纳能否动态捕获JVM引起的空指针异常

现在 Java 14 增加了一个新的语言特性来显示 NullPointerException 的根本原因.自 2006 年以来,此语言功能已成为 SAP 商业 JVM 的一部分.

在 Java 14 中,以下是示例 NullPointerException 异常消息:

<块引用>

在线程main"中java.lang.NullPointerException:无法调用java.util.List.size()";因为列表"为空

What are Null Pointer Exceptions (java.lang.NullPointerException) and what causes them?

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

解决方案

When you declare a reference variable (i.e., an object), you are really creating a pointer to an object. Consider the following code where you declare a variable of primitive type int:

int x;
x = 10;

In this example, the variable x is an int and Java will initialize it to 0 for you. When you assign the value of 10 on the second line, your value of 10 is written into the memory location referred to by x.

But, when you try to declare a reference type, something different happens. Take the following code:

Integer num;
num = new Integer(10);

The first line declares a variable named num, but it does not actually contain a primitive value yet. Instead, it contains a pointer (because the type is Integer which is a reference type). Since you have not yet said what to point to, Java sets it to null, which means "I am pointing to nothing".

In the second line, the new keyword is used to instantiate (or create) an object of type Integer, and the pointer variable num is assigned to that Integer object.

The NullPointerException (NPE) occurs when you declare a variable but did not create an object and assign it to the variable before trying to use the contents of the variable (called dereferencing). So you are pointing to something that does not actually exist.

Dereferencing usually happens when using . to access a method or field, or using [ to index an array.

If you attempt to dereference num before creating the object you get a NullPointerException. In the most trivial cases, the compiler will catch the problem and let you know that "num may not have been initialized," but sometimes you may write code that does not directly create the object.

For instance, you may have a method as follows:

public void doSomething(SomeObject obj) {
   // Do something to obj, assumes obj is not null
   obj.myMethod();
}

In which case, you are not creating the object obj, but rather assuming that it was created before the doSomething() method was called. Note, it is possible to call the method like this:

doSomething(null);

In which case, obj is null, and the statement obj.myMethod() will throw a NullPointerException.

If the method is intended to do something to the passed-in object as the above method does, it is appropriate to throw the NullPointerException because it's a programmer error and the programmer will need that information for debugging purposes.

In addition to NullPointerExceptions thrown as a result of the method's logic, you can also check the method arguments for null values and throw NPEs explicitly by adding something like the following near the beginning of a method:

// Throws an NPE with a custom error message if obj is null
Objects.requireNonNull(obj, "obj must not be null");

Note that it's helpful to say in your error message clearly which object cannot be null. The advantage of validating this is that 1) you can return your own clearer error messages and 2) for the rest of the method you know that unless obj is reassigned, it is not null and can be dereferenced safely.

Alternatively, there may be cases where the purpose of the method is not solely to operate on the passed in object, and therefore a null parameter may be acceptable. In this case, you would need to check for a null parameter and behave differently. You should also explain this in the documentation. For example, doSomething() could be written as:

/**
  * @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
    }
}

Finally, 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?

Sonar with find bugs can detect NPE. Can sonar catch null pointer exceptions caused by JVM Dynamically

Now Java 14 has added a new language feature to show the root cause of NullPointerException. This language feature has been part of SAP commercial JVM since 2006.

In Java 14, the following is a sample NullPointerException Exception message:

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

这篇关于什么是 NullPointerException,我该如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆