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

[英]What is a NullPointerException, and how do I fix it?


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

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

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

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

12 个解决方案

#1


3294  

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的变量:

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 it to 10 in the second line your value 10 is written into the memory location pointed to by x.

在此示例中,变量x是一个int,Java会将它初始化为0。当您在第二行中将其分配给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 contain a primitive value. Instead, it contains a pointer (because the type is Integer which is a reference type). Since you did not say as yet what to point to Java sets it to null, meaning "I am pointing at nothing".

第一行声明一个名为num的变量,但它不包含原始值。相反,它包含一个指针(因为类型是Integer,它是一个引用类型)。既然你还没有说什么指向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 this object. You can now reference the object using the dereferencing operator . (a dot).

在第二行中,new关键字用于实例化(或创建)Integer类型的对象,并为指针变量num分配此对象。您现在可以使用解除引用运算符引用该对象。 (一个点)。

The Exception that you asked about occurs when you declare a variable but did not create an object. 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 write code that does not directly create the object.

您询问的异常在声明变量但未创建对象时发生。如果尝试取消引用num BEFORE在创建对象之前会出现NullPointerException。在最琐碎的情况下,编译器将捕获问题并让您知道“num可能尚未初始化”,但有时您编写的代码不会直接创建对象。

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, rather assuming that it was created before the doSomething method was called. Unfortunately, it is possible to call the method like this:

在这种情况下,您不是在创建对象obj,而是假设它是在调用doSomething方法之前创建的。不幸的是,可以像这样调用方法:

doSomething(null);

In which case obj is 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.

在这种情况下,obj为null。如果该方法旨在对传入的对象执行某些操作,则抛出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. 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:

或者,可能存在这样的情况:该方法的目的不仅仅是对传入的对象进行操作,因此可以接受空参数。在这种情况下,您需要检查null参数并采取不同的行为。您还应该在文档中解释这一点。例如,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

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

#2


778  

NullPointerExceptions are exceptions that occur when you try to use a reference that points to no location in memory (null) as though it were referencing an object. Calling a method on a null reference or trying to access a field of a null reference will trigger a NullPointerException. These are the most common, but other ways are listed on the NullPointerException javadoc page.

NullPointerExceptions是当您尝试使用指向内存中没有位置的引用(null)时发生的异常,就好像它引用了一个对象一样。在空引用上调用方法或尝试访问空引用的字段将触发NullPointerException。这些是最常见的,但NullPointerException javadoc页面上列出了其他方法。

Probably the quickest example code I could come up with to illustrate a NullPointerException would be:

可能我用来说明NullPointerException的最快的示例代码是:

public class Example {    public static void main(String[] args) {        Object obj = null;        obj.hashCode();    }}

On the first line inside main, I'm explicitly setting the Object reference obj equal to null. This means I have a reference, but it isn't pointing to any object. After that, I try to treat the reference as though it points to an object by calling a method on it. This results in a NullPointerException because there is no code to execute in the location that the reference is pointing.

在main中的第一行,我明确地将Object引用obj设置为null。这意味着我有一个引用,但它没有指向任何对象。之后,我尝试将引用视为通过调用其上的方法指向对象。这会导致NullPointerException,因为没有代码可以在引用指向的位置执行。

(This is a technicality, but I think it bears mentioning: A reference that points to null isn't the same as a C pointer that points to an invalid memory location. A null pointer is literally not pointing anywhere, which is subtly different than pointing to a location that happens to be invalid.)

(这是技术性的,但我认为值得一提的是:指向null的引用与指向无效内存位置的C指针不同。空指针实际上并不指向任何位置,这与指向恰好无效的位置。)

#3


628  

What is a NullPointerException?

A good place to start is the JavaDocs. They have this covered:

一个好的起点是JavaDocs。他们有这个涵盖:

Thrown when an application attempts to use null in a case where an object is required. These include:

当应用程序在需要对象的情况下尝试使用null时抛出。这些包括:

  • Calling the instance method of a null object.
  • 调用null对象的实例方法。

  • Accessing or modifying the field of a null object.
  • 访问或修改空对象的字段。

  • Taking the length of null as if it were an array.
  • 将null的长度视为数组。

  • Accessing or modifying the slots of null as if it were an array.
  • 访问或修改null的插槽,就像它是一个数组一样。

  • Throwing null as if it were a Throwable value.
  • 抛出null,好像它是一个Throwable值。

Applications should throw instances of this class to indicate other illegal uses of the null object.

应用程序应该抛出此类的实例以指示null对象的其他非法使用。

It is also the case that if you attempt to use a null reference with synchronized, that will also throw this exception, per the JLS:

还有一种情况是,如果您尝试使用带有synchronized的空引用,那么每个JLS也会抛出此异常:

SynchronizedStatement:    synchronized ( Expression ) Block
  • Otherwise, if the value of the Expression is null, a NullPointerException is thrown.
  • 否则,如果Expression的值为null,则抛出NullPointerException。

How do I fix it?

So you have a NullPointerException. How do you fix it? Let's take a simple example which throws a NullPointerException:

所以你有一个NullPointerException。你是如何解决的?让我们举一个抛出NullPointerException的简单示例:

public class Printer {    private String name;    public void setName(String name) {        this.name = name;    }    public void print() {        printString(name);    }    private void printString(String s) {        System.out.println(s + " (" + s.length() + ")");    }    public static void main(String[] args) {        Printer printer = new Printer();        printer.print();    }}

Identify the null values

标识空值

The first step is identifying exactly which values are causing the exception. For this, we need to do some debugging. It's important to learn to read a stacktrace. This will show you where the exception was thrown:

第一步是确切地确定导致异常的值。为此,我们需要做一些调试。学习阅读堆栈跟踪很重要。这将显示抛出异常的位置:

Exception in thread "main" java.lang.NullPointerException    at Printer.printString(Printer.java:13)    at Printer.print(Printer.java:9)    at Printer.main(Printer.java:19)

Here, we see that the exception is thrown on line 13 (in the printString method). Look at the line and check which values are null byadding logging statements or using a debugger. We find out that s is null, and calling the length method on it throws the exception. We can see that the program stops throwing the exception when s.length() is removed from the method.

在这里,我们看到在第13行抛出异常(在printString方法中)。查看该行并通过添加日志记录语句或使用调试器来检查哪些值为null。我们发现s为null,并且在其上调用length方法会抛出异常。我们可以看到,当从方法中删除s.length()时,程序停止抛出异常。

Trace where these values come from

追踪这些值来自哪里

Next check where this value comes from. By following the callers of the method, we see that s is passed in with printString(name) in the print() method, and this.name is null.

接下来检查此值的来源。通过跟随方法的调用者,我们看到s在print()方法中使用printString(name)传入,而this.name为null。

Trace where these values should be set

跟踪应设置这些值的位置

Where is this.name set? In the setName(String) method. With some more debugging, we can see that this method isn't called at all. If the method was called, make sure to check the order that these methods are called, and the set method isn't called after the print method.

this.name设置在哪里?在setName(String)方法中。通过一些更多的调试,我们可以看到根本没有调用此方法。如果调用该方法,请确保检查调用这些方法的顺序,并且在print方法之后不调用set方法。

This is enough to give us a solution: add a call to printer.setName() before calling printer.print().

这足以为我们提供一个解决方案:在调用printer.print()之前添加对printer.setName()的调用。

Other fixes

The variable can have a default value (and setName can prevent it being set to null):

该变量可以具有默认值(并且setName可以防止将其设置为null):

private String name = "";

Either the print or printString method can check for null, for example:

print或printString方法可以检查null,例如:

printString((name == null) ? "" : name);

Or you can design the class so that name always has a non-null value:

或者,您可以设计类,以便名称始终具有非null值:

public class Printer {    private final String name;    public Printer(String name) {        this.name = Objects.requireNonNull(name);    }    public void print() {        printString(name);    }    private void printString(String s) {        System.out.println(s + " (" + s.length() + ")");    }    public static void main(String[] args) {        Printer printer = new Printer("123");        printer.print();    }}

See also:

I still can't find the problem

If you tried to debug the problem and still don't have a solution, you can post a question for more help, but make sure to include what you've tried so far. At a minimum, include the stacktrace in the question, and mark the important line numbers in the code. Also, try simplifying the code first (see SSCCE).

如果您尝试调试问题但仍然没有解决方案,可以发布问题以获得更多帮助,但请确保包含您目前为止尝试过的内容。至少要在问题中包含堆栈跟踪,并在代码中标记重要的行号。另外,请先尝试简化代码(请参阅SSCCE)。

#4


449  

Question: What causes a NullPointerException (NPE)?

As you should know, Java types are divided into primitive types (boolean, int, etc.) and reference types. Reference types in Java allow you to use the special value null which is the Java way of saying "no object".

您应该知道,Java类型分为基本类型(布尔值,整数等)和引用类型。 Java中的引用类型允许您使用特殊值null,这是Java表示“无对象”的方式。

A NullPointerException is thrown at runtime whenever your program attempts to use a null as if it was a real reference. For example, if you write this:

每当程序尝试使用null时,就会在运行时抛出NullPointerException,就像它是真正的引用一样。例如,如果你这样写:

public class Test {    public static void main(String[] args) {        String foo = null;        int length = foo.length();   // HERE    }}

the statement labelled "HERE" is going to attempt to run the length() method on a null reference, and this will throw a NullPointerException.

标记为“HERE”的语句将尝试在null引用上运行length()方法,这将抛出NullPointerException。

There are many ways that you could use a null value that will result in a NullPointerException. In fact, the only things that you can do with a null without causing an NPE are:

有许多方法可以使用null值,这将导致NullPointerException。实际上,在没有导致NPE的情况下,使用null可以执行的唯一操作是:

  • assign it to a reference variable or read it from a reference variable,
  • 将其分配给引用变量或从引用变量中读取它,

  • assign it to an array element or read it from an array element (provided that array reference itself is non-null!),
  • 将它分配给数组元素或从数组元素中读取它(假设数组引用本身是非空的!),

  • pass it as a parameter or return it as a result, or
  • 将其作为参数传递或作为结果返回,或

  • test it using the == or != operators, or instanceof.
  • 使用==或!=运算符或instanceof测试它。

Question: How do I read the NPE stacktrace?

Suppose that I compile and run the program above:

假设我编译并运行上面的程序:

$ javac Test.java $ java TestException in thread "main" java.lang.NullPointerException    at Test.main(Test.java:4)$

First observation: the compilation succeeds! The problem in the program is NOT a compilation error. It is a runtime error. (Some IDEs may warn your program will always throw an exception ... but the standard javac compiler doesn't.)

首先观察:编译成功!程序中的问题不是编译错误。这是一个运行时错误。 (某些IDE可能会警告您的程序将始终抛出异常......但标准的javac编译器不会。)

Second observation: when I run the program, it outputs two lines of "gobbledy-gook". WRONG!! That's not gobbledy-gook. It is a stacktrace ... and it provides vital information that will help you track down the error in your code, if you take the time to read it carefully.

第二个观察:当我运行程序时,它会输出两行“gobbledy-gook”。错误!!那不是狼吞虎咽。它是一个堆栈跟踪...它提供了重要的信息,可以帮助您跟踪代码中的错误,如果您花时间仔细阅读它。

So let's look at what it says:

那么让我们来看看它的内容:

Exception in thread "main" java.lang.NullPointerException

The first line of the stack trace tells you a number of things:

堆栈跟踪的第一行告诉您许多事情:

  • It tells you the name of the Java thread in which the exception was thrown. For a simple program with one thread (like this one), it will be "main". Let's move on ...
  • 它告诉您抛出异常的Java线程的名称。对于一个带有一个线程的简单程序(比如这个),它将是“主”。让我们继续 ...

  • It tells you the full name of the exception that was thrown; i.e. java.lang.NullPointerException.
  • 它告诉你抛出的异常的全名;即java.lang.NullPointerException。

  • If the exception has an associated error message, that will be output after the exception name. NullPointerException is unusual in this respect, because it rarely has an error message.
  • 如果异常具有关联的错误消息,则将在异常名称后输出。 NullPointerException在这方面很不寻常,因为它很少有错误消息。

The second line is the most important one in diagnosing an NPE.

第二行是诊断NPE中最重要的一行。

at Test.main(Test.java:4)

This tells us a number of things:

这告诉了我们许多事情:

  • "at Test.main" says that we were in the main method of the Test class.
  • “在Test.main”说我们是Test类的主要方法。

  • "Test.java:4" gives the source filename of the class, AND it tells us that the statement where this occurred is in line 4 of the file.
  • “Test.java:4”给出了类的源文件名,它告诉我们发生这种情况的语句在文件的第4行。

If you count the lines in the file above, line 4 is the one that I labeled with the "HERE" comment.

如果你计算上面文件中的行,第4行是我用“HERE”注释标记的行。

Note that in a more complicated example, there will be lots of lines in the NPE stack trace. But you can be sure that the second line (the first "at" line) will tell you where the NPE was thrown1.

请注意,在一个更复杂的示例中,NPE堆栈跟踪中会有很多行。但是你可以确定第二行(第一行“at”行)会告诉你NPE被抛出的位置1。

In short the stack trace will tell us unambiguously which statement of the program has thrown the NPE.

简而言之,堆栈跟踪将毫不含糊地告诉我们程序的哪个语句抛出了NPE。

1 - Not quite true. There are things called nested exceptions...

1 - 不完全正确。有些东西叫做嵌套异常......

Question: How do I track down the cause of the NPE exception in my code?

This is the hard part. The short answer is to apply logical inference to the evidence provided by the stack trace, the source code and the relevant API documentation.

这是困难的部分。简短的回答是对堆栈跟踪,源代码和相关API文档提供的证据应用逻辑推理。

Let's illustrate with the simple example (above) first. We start by looking at the line that the stack trace has told us is where the NPE happened:

让我们首先用简单的例子(上面)来说明。我们首先看一下堆栈跟踪告诉我们NPE发生的位置:

int length = foo.length(); // HERE

How can that throw an NPE?

如何抛出NPE?

In fact there is only one way: it can only happen if foo has the value null. We then try to run the length() method on null and .... BANG!

实际上只有一种方法:只有当foo的值为null时才会发生。然后我们尝试在null和....上运行length()方法!

But (I hear you say) what if the NPE was thrown inside the length() method call?

但是(我听你说)如果NPE被引入length()方法调用中会怎么样?

Well, if that happened, the stack trace would look different. The first "at" line would say that the exception was thrown in some line in the java.lang.String class, and line 4 of Test.java would be the second "at" line.

好吧,如果发生这种情况,堆栈跟踪看起来会有所不同。第一个“at”行表示异常是在java.lang.String类的某行中抛出的,Test.java的第4行是第二个“at”行。

So where did that null come from? In this case it is obvious, and it is obvious what we need to do to fix it. (Assign a non-null value to foo.)

那么null是从哪里来的?在这种情况下,很明显,我们需要做的是修复它。 (为foo指定一个非空值。)

OK, so let's try a slightly more tricky example. This will require some logical deduction.

好的,让我们尝试一个稍微棘手的例子。这将需要一些逻辑演绎。

public class Test {    private static String[] foo = new String[2];    private static int test(String[] bar, int pos) {        return bar[pos].length();    }    public static void main(String[] args) {        int length = test(foo, 1);    }}$ javac Test.java $ java TestException in thread "main" java.lang.NullPointerException    at Test.test(Test.java:6)    at Test.main(Test.java:10)$ 

So now we have two "at" lines. The first one is for this line:

所以现在我们有两条“at”线。第一个是这一行:

return args[pos].length();

and the second one is for this line:

第二个就是这一行:

int length = test(foo, 1);

Looking at the first line, how could that throw an NPE? There are two ways:

看第一行,怎么会抛出一个NPE?有两种方法:

  • If the value of bar is null then bar[pos] will throw an NPE.
  • 如果bar的值为null,则bar [pos]将抛出NPE。

  • If the value of bar[pos] is null then calling length() on it will throw an NPE.
  • 如果bar [pos]的值为null,则在其上调用length()将抛出NPE。

Next, we need to figure out which of those scenarios explains what is actually happening. We will start by exploring the first one:

接下来,我们需要弄清楚哪些场景解释了实际发生的情况。我们将从探索第一个开始:

Where does bar come from? It is a parameter to the test method call, and if we look at how test was called, we can see that it comes from the foo static variable. In addition, we can see clearly that we initialized foo to a non-null value. That is sufficient to tentatively dismiss this explanation. (In theory, something else could change foo to null ... but that is not happening here.)

酒吧从哪里来?它是测试方法调用的参数,如果我们看看如何调用test,我们可以看到它来自foo静态变量。另外,我们可以清楚地看到我们将foo初始化为非null值。这足以暂时驳回这一解释。 (理论上,其他东西可以改变foo为null ......但这不会发生在这里。)

So what about our second scenario? Well, we can see that pos is 1, so that means that foo[1] must be null. Is that possible?

那么我们的第二个场景呢?好吧,我们可以看到pos是1,这意味着foo [1]必须为null。那可能吗?

Indeed it is! And that is the problem. When we initialize like this:

的确是!这就是问题所在。当我们这样初始化时:

private static String[] foo = new String[2];

we allocate a String[] with two elements that are initialized to null. After that, we have not changed the contents of foo ... so foo[1] will still be null.

我们分配一个String [],其中包含两个初始化为null的元素。之后,我们没有改变foo的内容...所以foo [1]仍然是null。

#5


374  

It's like you are trying to access an object which is null. Consider below example:

这就像你试图访问一个null的对象。考虑下面的例子:

TypeA objA;

At this time you have just declared this object but not initialized or instantiated. And whenever you try to access any property or method in it, it will throw NullPointerException which makes sense.

此时您刚刚声明了此对象但未初始化或实例化。每当你尝试访问其中的任何属性或方法时,它都会抛出NullPointerException,这是有道理的。

See this below example as well:

请参阅以下示例:

String a = null;System.out.println(a.toString()); // NullPointerException will be thrown

#6


323  

A null pointer exception is thrown when an application attempts to use null in a case where an object is required. These include:

当应用程序在需要对象的情况下尝试使用null时,将引发空指针异常。这些包括:

  1. Calling the instance method of a null object.
  2. 调用null对象的实例方法。

  3. Accessing or modifying the field of a null object.
  4. 访问或修改空对象的字段。

  5. Taking the length of null as if it were an array.
  6. 将null的长度视为数组。

  7. Accessing or modifying the slots of null as if it were an array.
  8. 访问或修改null的插槽,就像它是一个数组一样。

  9. Throwing null as if it were a Throwable value.
  10. 抛出null,好像它是一个Throwable值。

Applications should throw instances of this class to indicate other illegal uses of the null object.

应用程序应该抛出此类的实例以指示null对象的其他非法使用。

Reference: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

#7


300  

A NULL pointer is one that points to nowhere. When you dereference a pointer p, you say "give me the data at the location stored in "p". When p is a null pointer, the location stored in p is nowhere, you're saying "give me the data at the location 'nowhere'". Obviously, it can't do this, so it throws a NULL pointer exception.

NULL指针是指向无处的指针。当您取消引用指针p时,您说“给我存储在”p“中的位置的数据。当p是空指针时,存储在p中的位置无处可去,您说”在该位置给我数据'无处'。显然,它无法执行此操作,因此会抛出NULL指针异常。

In general, it's because something hasn't been initialized properly.

一般来说,这是因为某些东西尚未正确初始化。

#8


287  

A lot of explanations are already present to explain how it happens and how to fix it, but you should also follow best practices to avoid NullPointerException at all.

已经有很多解释来解释它是如何发生的以及如何解决它,但你也应该遵循最佳实践来避免NullPointerException。

See also:A good list of best practices

另请参阅:最佳实践清单

I would add, very important, make a good use of the final modifier.Using the "final" modifier whenever applicable in Java

我想补充一点,非常重要的是,要好好利用final修饰符。只要适用于Java,就使用“final”修饰符

Summary:

  1. Use the final modifier to enforce good initialization.
  2. 使用final修饰符强制执行良好的初始化。

  3. Avoid returning null in methods, for example returning empty collections when applicable.
  4. 避免在方法中返回null,例如在适用时返回空集合。

  5. Use annotations @NotNull and @Nullable
  6. 使用注释@NotNull和@Nullable

  7. Fail fast and use asserts to avoid propagation of null objects through the whole application when they shouldn't be null.
  8. 快速失败并使用断言来避免null对象在不应为null时在整个应用程序中传播。

  9. Use equals with a known object first: if("knownObject".equals(unknownObject)
  10. 首先使用equals与已知对象:if(“knownObject”.equals(unknownObject)

  11. Prefer valueOf() over toString().
  12. 首选valueOf()over toString()。

  13. Use null safe StringUtils methods StringUtils.isEmpty(null).
  14. 使用null安全StringUtils方法StringUtils.isEmpty(null)。

#9


284  

A null pointer exception is an indicator that you are using an object without initializing it.

空指针异常是指示您正在使用对象而不初始化它。

For example, below is a student class which will use it in our code.

例如,下面是一个将在我们的代码中使用它的学生类。

public class Student {    private int id;    public int getId() {        return this.id;    }    public setId(int newId) {        this.id = newId;    }}

The below code gives you a null pointer exception.

下面的代码为您提供了空指针异常。

public class School {    Student obj_Student;    public School() {        try {            obj_Student.getId();        }        catch(Exception e) {            System.out.println("Null Pointer ");        }    }}

Because you are using Obj_Student, but you forgot to initialize it like in thecorrect code shown below:

因为您使用的是Obj_Student,但是您忘记将其初始化,就像在下面显示的正确代码中一样:

public class School {    Student obj_Student;    public School() {        try {            obj_Student = new Student();            obj_Student.setId(12);            obj_Student.getId();        }        catch(Exception e) {            System.out.println("Null Pointer ");        }    }}

#10


277  

In Java, everything is in the form of a class.

在Java中,一切都是以类的形式出现的。

If you want to use any object then you have two phases:

如果您想使用任何对象,那么您有两个阶段:

  1. Declare
  2. Initialization

Example:

  • Declaration: Object a;
  • 声明:对象a;

  • Initialization: a=new Object();
  • 初始化:a = new Object();

Same for the array concept

对于阵列概念也是如此

  • Declaration: Item i[]=new Item[5];
  • 声明:项目i [] =新项目[5];

  • Initialization: i[0]=new Item();
  • 初始化:i [0] = new Item();

If you are not giving the initialization section then the NullpointerException arise.

如果您没有给出初始化部分,则会出现NullpointerException。

#11


266  

In Java all the variables you declare are actually "references" to the objects (or primitives) and not the objects themselves.

在Java中,您声明的所有变量实际上都是对象(或基元)的“引用”,而不是对象本身。

When you attempt to execute one object method, the reference asks the living object to execute that method. But if the reference is referencing NULL (nothing, zero, void, nada) then there is no way the method gets executed. Then the runtime let you know this by throwing a NullPointerException.

当您尝试执行一个对象方法时,该引用会要求生命对象执行该方法。但是如果引用引用NULL(nothing,zero,void,nada),则该方法无法执行。然后运行时通过抛出NullPointerException让您知道这一点。

Your reference is "pointing" to null, thus "Null -> Pointer".

你的引用是“指向”null,因此“Null - > Pointer”。

The object lives in the VM memory space and the only way to access it is using this references. Take this example:

该对象位于VM内存空间中,访问它的唯一方法是使用此引用。举个例子:

public class Some {    private int id;    public int getId(){        return this.id;    }    public setId( int newId ) {        this.id = newId;    }}

And on another place in your code:

在代码中的另一个位置:

Some reference = new Some();    // Point to a new object of type Some()Some otherReference = null;     // Initiallly this points to NULLreference.setId( 1 );           // Execute setId method, now private var id is 1System.out.println( reference.getId() ); // Prints 1 to the consoleotherReference = reference      // Now they both point to the only object.reference = null;               // "reference" now point to null.// But "otherReference" still point to the "real" object so this print 1 too...System.out.println( otherReference.getId() );// Guess what will happenSystem.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

This an important thing to know - when there are no more references to an object (in the example above when reference and otherReference both point to null) then the object is "unreachable". There is no way we can work with it, so this object is ready to be garbage collected, and at some point, the VM will free the memory used by this object and will allocate another.

这是一个重要的事情要知道 - 当没有更多对象的引用时(在上面的例子中,当reference和otherReference都指向null)时,该对象是“无法访问的”。我们无法使用它,因此该对象已准备好进行垃圾收集,并且在某些时候,VM将释放此对象使用的内存并将分配另一个。

#12


252  

Another occurrence of a NullPointerException occurs when one declares an object array, then immediately tries to dereference elements inside of it.

当一个声明一个对象数组时,会发生另一次NullPointerException,然后立即尝试取消引用它内部的元素。

String[] phrases = new String[10];String keyPhrase = "Bird";for(String phrase : phrases) {    System.out.println(phrase.equals(keyPhrase));}

This particular NPE can be avoided if the comparison order is reversed; namely, use .equals on a guaranteed non-null object.

如果比较顺序颠倒,则可以避免这种特殊的NPE;即,在保证的非null对象上使用.equals。

All elements inside of an array are initialized to their common initial value; for any type of object array, that means that all elements are null.

数组内的所有元素都初始化为它们的公共初始值;对于任何类型的对象数组,这意味着所有元素都为null。

You must initialize the elements in the array before accessing or dereferencing them.

在访问或取消引用它们之前,必须初始化数组中的元素。

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};String keyPhrase = "Bird";for(String phrase : phrases) {    System.out.println(phrase.equals(keyPhrase));}

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2016/05/26/8800750c76119e35239d86c2706384d7.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号