When you declare a reference variable (ie 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
的变量:)
int x;
x = 10;
In this example, the variable x
is an int
and Java will initialize it to 0
for you.
(在此示例中,变量x
是一个int
,Java会为您将其初始化为0
。)
When you assign it the value of 10
on the second line, your value of 10
is written into the memory location referred to by x
. (在第二行为其分配值10
时,会将值10
写入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.
(第一行声明了一个名为num
的变量,但实际上尚未包含原始值。)
Instead, it contains a pointer (because the type is Integer
which is a reference type). (相反,它包含一个指针(因为类型是Integer
,它是引用类型)。)
Since you have not yet said what to point to, Java sets it to null
, which means " I am pointing to nothing ". (由于您尚未说出要指向的内容,因此Java将其设置为null
,这意味着“ 我什么都没有指向 ”。)
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.
(在第二行中, new
关键字用于实例化(或创建) Integer
类型的对象,并将指针变量num
分配给该Integer
对象。)
The NullPointerException
occurs when you declare a variable but did not create an object.
(当您声明变量但未创建对象时,会发生NullPointerException
。)
So you are pointing to something that does not actually exist. (因此,您指向的是实际上不存在的东西。)
If you attempt to dereference num
BEFORE creating the object you get a NullPointerException
.
(如果在创建对象之前尝试取消引用num
,则会收到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. (在大多数情况下,编译器会捕获该问题,并告知您“ num may not have been initialized
”,但是有时您可能会编写不直接创建该对象的代码。)
For instance, you may have a method as follows:
(例如,您可能具有如下方法:)
public void doSomething(SomeObject obj) {
//do something to obj
}
In which case, you are not creating the object obj
, but rather assuming that it was created before the doSomething()
method was called.
(在这种情况下,您不是在创建对象obj
,而是假设它是在调用doSomething()
方法之前创建的。)
Note, it is possible to call the method like this: (注意,可以这样调用方法:)
doSomething(null);
In which case, obj
is null
.
(在这种情况下, obj
为null
。)
If the method is intended to do something to the passed-in object, it is appropriate to throw the NullPointerException
because it's a programmer error and the programmer will need that information for debugging purposes. (如果该方法旨在对传入的对象做一些事情,则抛出NullPointerException
是适当的,因为它是程序员的错误,程序员将需要该信息来进行调试。)
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.
(替代地,在某些情况下,该方法的目的不仅是要对传入的对象进行操作,因此null参数是可以接受的。)
In this case, you would need to check for a null parameter and behave differently. (在这种情况下,您将需要检查null参数并改变行为。)
You should also explain this in the documentation. (您还应该在文档中对此进行解释。)
For example, doSomething()
could be written as: (例如, 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
}
}
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 findbugs can detect NPE.
(带有findbug的声纳可以检测NPE。)
Can sonar catch null pointer exceptions caused by JVM Dynamically (声纳能否动态捕获由JVM引起的空指针异常)