空指针异常(java.lang.NullPointerException是什么?是什么导致的?
可以使用哪些方法/工具来确定导致异常终止的原因,从而阻止异常导致程序过早终止?
当您声明引用变量(即对象)时,实际上是在创建指向对象的指针。考虑以下代码,在其中声明一个基本类型为int的变量:
在这个例子中,变量x是一个EDCOX1,0,而Java将初始化为0。当您在第二行将它赋给10时,您的值10将写入x指向的内存位置。
但是,当您试图声明引用类型时,会发生一些不同的情况。采用以下代码:
第一行声明一个名为num的变量,但它不包含基元值。相反,它包含一个指针(因为类型是Integer,它是一个引用类型)。因为你没有说什么指向Java,将它设置为NULL,意思是"我指不到任何东西"。
在第二行中,new关键字用于实例化(或创建)integer类型的对象,并为指针变量num分配该对象。现在可以使用取消引用操作符.引用对象(一个点)。
当您声明变量但没有创建对象时,您询问的Exception会发生。如果在创建对象之前试图取消引用num,则会得到NullPointerException。在最普通的情况下,编译器会发现问题并告诉您"num可能尚未初始化",但有时编写的代码不会直接创建对象。
例如,您可能有如下方法:
1 2 3
| public void doSomething(SomeObject obj) {
//do something to obj
} |
在这种情况下,您不会创建对象obj,而是假设它是在调用doSomething方法之前创建的。不幸的是,可以这样调用方法:
在这种情况下,obj为空。如果该方法打算对传入的对象执行某些操作,则可以抛出NullPointerException,因为它是一个程序员错误,程序员需要该信息进行调试。
或者,在某些情况下,方法的目的不仅仅是对传入对象进行操作,因此可以接受空参数。在这种情况下,您需要检查空参数并以不同的方式进行操作。您还应该在文档中对此进行解释。例如,doSomething可以写成:
1 2 3 4 5 6 7 8 9 10 11
| /**
* @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
}
} |
最后,如何使用堆栈跟踪确定异常和原因
- "避免此类异常的最佳方法是,在没有自己创建对象时始终检查空值。"如果调用方传递空值,但空值不是该方法的有效参数,则正确的做法是向调用方引发异常,因为这是调用方的错误。悄悄地忽略无效的输入,在方法中什么都不做是非常糟糕的建议,因为它隐藏了问题。
- 我会在这篇文章中加上一句评论,解释在使用autoboxing时,即使是对原语的赋值也会导致NPE:如果b是一个Integer,int a=b可以抛出一个NPE。在某些情况下,这会使调试混乱。
- 是否可以从Web浏览器捕获Web应用程序引发的NPE?就像它会在Web浏览器的视图页面源中显示一样。
- 是,在调用对象的方法或尝试访问对象可能具有的变量之前,请检查该对象是否等于空。有时,构造代码有助于避免空指针异常。例如,当使用常量字符串检查输入字符串时,您应该像这里这样从常量字符串开始:if("somestring".equals(input string))//即使input string为空,也不会引发异常。所以你可以做很多事情来确保安全。
- 另一个小的补充是,如果逻辑不强制不返回值,或者我们想要强制签入调用者,那么尝试使用可选的返回类型。
- 避免代码中出现NullPointerException问题的另一种方法是使用@Nullable和@NotNull注释。以下答案提供了更多有关此的信息。尽管这个答案是关于IntellijIDE的,但它也适用于其他工具,正如来自Teh评论的Apparanet。(顺便问一下,我不允许直接编辑这个答案,也许作者可以添加它?)
- 因为在一个方法中声明它,Java将变量设置为其默认值是不正确的。它只对实例变量执行此操作。如果您在方法中声明一个变量而不给它赋值,然后尝试使用它,您将得到variable may not be initialized编译器错误。
- @这个例子从Boann开始是没有意义的,因为integer是不可变的类型。你不能"对num做点什么"。
- 指针是基元类型的基元值。不是指尖。
- NPE的另一个常见的根本原因是从查询中创建一个对象并调用该对象的属性,而不检查它是否为空。例如:Document document = repo.getDocumentSetByFilter(filter).get(0).getFirstDocument();这里可以通过在.get(0)之后和.getFirstDocument();之前执行空检查来修复NPE。
- 此外,我认为重要的是要澄清,与检查异常相反,NullPointerException是一个未检查的异常。这是一个很好的开始学习检查异常和未检查异常之间的区别的地方。
- 很好的解释,但有时通过if和else处理这个异常并不是一个好的实践,请考虑您正在提供的服务:如果您让消费者知道请求导致了空指针异常,那就更好了。有时通过抛出适当的异常来处理这些事件会更有用。
- @文森特也许你可以补充一下,当自动拆箱发生时,有时会抛出一个NullPointerException:Boolean b;,然后是if (b) { ... }。有时会让新手感到困惑。
- 使用空对象设计模式怎么样?何时推荐?
- 对NPES的一般建议:在公共/包/受保护方法上,务必验证null上的任何传入参数,并包括开发人员友好的消息:if(null==someParameter)throw new nullpointerception("someParameter is null");if someParameter is a DAO, and I know it **must** be fully persisted when handled over, I also check it's primary key below above general check: if(someParameter.getsomeID()==null)throw new nullpointerception("someParametereter.someid为空);`。
- 为了确保ID永远不会低于1:if (someParameter.getSomeId() < 1) { throw new IllegalArgumentException("someParameter.someId="+someParameter.getSomeId()+" is invalid");,通过这种方式,我确保正确调用我的public/package/protected(而不是private,因为这使得单元测试更加困难)。
- 为NullPointerException is when an Application to扔摒弃使用对象参考that has the安空值。这些方法包括:电话安审,所有的空对象模式上的参考。accessing安审或调整对象模式的所有Field of the零参考。if the reference type is an the length of阵列型,以零参考。if the reference type is an阵列型槽调整,accessing or the of a零参考。if the reference type is a subtype of异常,将零参考。
- 当你访问Property of some安在线参考对象是空,空指针异常,然后扔了。
- 显示一个"伙伴"的兴趣从事Java nullpointerexceptions since is the optional<T>8级。如果misused does not but if伙伴EN EN EN can help enourmously used by enforcing正确检查的地方哪里可在线passed零模式的方法。is that the想法在EN EN在the actual粘贴对象,你是通过提供一ispresent method to check and whether or not present is a可变。尽管这是done by an!茶叶优势= null检查,如果你see that is the清晰度returned by that is an optional method在instantly,你知道它可以是零。
- 因为它是downvoted factually that between the local variable declaring incorrect numassigning安布尔值参考EN Integerto its null,会好的。事实上,它是unassigned布尔值,想使用它是在编译时错误。nullwhen to get initialized变量instance is an object above created,but the example to be about a local variable似乎。
- 如果你是我会使用jdk8蓝晶石ofnullable API。optional.ofnullable(选择=空);();(assertfalse opt.ispresent)
- 没有人在这里surprisingly上述静态代码分析。IntelliJ,Eclipse和帮助识别这些错误给find在发展。步骤:fromdev.com / R在2018年zwnj/02/good-bye-nullpointerexception-in-java.ht &;& # 8203;毫升
NullPointerExceptions是当您试图使用指向内存中没有位置(空)的引用时发生的异常,就好像它引用了一个对象一样。对空引用调用方法或尝试访问空引用的字段将触发NullPointerException。这些是最常见的,但其他方法在NullPointerExceptionjavadoc页面中列出。
我能想到的最快的示例代码可能是:
1 2 3 4 5 6 7 8
| public class Example {
public static void main (String[] args ) {
Object obj = null;
obj. hashCode();
}
} |
在main内的第一行,我明确设置Object引用obj等于null。这意味着我有一个引用,但它没有指向任何对象。在那之后,我尝试将引用视为它通过调用一个方法指向一个对象。这会导致NullPointerException,因为在引用指向的位置没有要执行的代码。
(这是一个技术性的问题,但我认为应该提到:指向空值的引用与指向无效内存位置的C指针不同。从字面上看,空指针不指向任何地方,这与指向恰好无效的位置略有不同。)
- 我理解你在那里写的所有东西,但仅仅是因为我已经编码了一段时间,知道什么是"指针"和"引用"(就这点而言,空值是什么)。当我试图深入到这样的解释中时,我的学生们会用斜视的眼光看着我,因为没有足够的背景。
- @谢谢你的反馈,你说得对。在互联网上,很难真正判断某人在哪里,以及在什么程度上开始解释是安全的。我再修改一下。
- 在实际中,获得nullpointerException的一种更常见的方法是忘记在使用之前将成员变量显式初始化为除null之外的某个对象,如下所示。对于局部变量,编译器会捕获这个错误,但在本例中不会。也许这会对您的答案有帮助吗?
- 引用不"指向空"。它们是空的,或者指向一个对象。
- @EJP"空指针实际上不指向任何地方…"
- 没错。所以它不"指向空"。
- @EJP,这正是那个段落所指出的。
- @EJP我认为你的观点是有效的,所以我更新了答案以使其更清晰,并避免在它所做的地方说"指向空"。
- @史蒂文鲍威尔,我很久以前就说过我不想改变我的答案。请尊重原作者的意图。
- 很抱歉,我按照StackOverflow项目顶部的要求"改进答案"(此问题的答案是一项协作工作:如果您看到可以改进的内容,只需编辑答案即可改进!)我不同意您的版本更好,imo@ejb有有效的观点;但是欢迎您保持您的答案完整,尽管它令人困惑。
- 我不确定Java中是否相同,但是在C中,EDOCX1 0是指向内存位置0的指针,它被标准定义为无效的内存位置(在这个意义上,您不能在那里读取/写入值)。因此,如果在Java中是相同的,那么更精确的可能是"指向一个特定的、预定的无效内存点,意思是‘没有价值’"。
- @qpaystaxes在c中的null几乎总是一个文本零(o的宏)。如果解释为指针,则指向内存地址零,通常不可寻址,当然也不可更新。它在Java中是不一样的,其中EDCOX1〔0〕是关键字,并且表示可分配给对象变量或字段的(无类型)值。它不"指向空",根本不是指针。
- 我发现这个例子有误导性。如果hashcode()是一个扩展方法,那么调用很可能已经通过了。更好的方法是显示尝试访问字段的示例。
- MadsBoyd Madsen,这是2008编写的Java代码。没有什么误导性的。
- @Madsboyd Madsen不用担心。这篇文章发表的那一年并没有像往常那样显示出来,因为它是一个社区维基帖子,已经被编辑了很多次。
什么是NullPointerException?
一个好的起点是javadocs。它们包括:
Thrown when an application attempts to use null in a case where an
object is required. These include:
-
Calling the instance method of a null object.
-
Accessing or modifying the field of a null object.
-
Taking the length of null as if it were an array.
-
Accessing or modifying the slots of null as if it were an array.
-
Throwing null as if it were a Throwable value.
Applications should throw instances of this class to indicate other
illegal uses of the null object.
另外,如果您尝试对synchronized使用空引用,也会根据jls引发此异常:
1 2
| SynchronizedStatement:
synchronized ( Expression ) Block |
-
Otherwise, if the value of the Expression is null, a NullPointerException is thrown.
我该怎么修?
所以你有一个NullPointerException。你怎么修理它?让我们举一个简单的例子,它抛出一个NullPointerException:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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();
}
} |
标识空值
第一步是准确识别导致异常的值。为此,我们需要进行一些调试。学习读stacktrace很重要。这将显示引发异常的位置:
1 2 3 4
| 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) |
这里,我们看到异常被抛出在第13行(在printString方法中)。查看行并检查哪些值为空添加日志语句或使用调试器。我们发现s是空的,对它调用length方法会抛出异常。我们可以看到,当从方法中删除s.length()时,程序停止抛出异常。
跟踪这些值的来源
接下来检查这个值的来源。通过跟踪方法的调用方,我们发现s在print()方法中与printString(name)一起传入,this.name为空。
跟踪应在何处设置这些值
this.name在哪里?在setName(String)方法中。通过更多的调试,我们可以看到这个方法根本没有被调用。如果调用了方法,请确保检查调用这些方法的顺序,并且不会在print方法之后调用set方法。
这足以给我们提供一个解决方案:在调用printer.print()之前,向printer.setName()添加一个调用。
其他修正
变量可以有一个默认值(并且setName可以防止它被设置为空):
print或printString方法可以检查是否为空,例如:
1
| printString((name == null) ?"" : name); |
或者可以设计类,使name始终具有非空值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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();
}
} |
参见:
我还是找不到问题
如果您试图调试问题,但仍然没有解决方案,您可以发布一个问题以获得更多帮助,但请确保包含迄今为止所尝试的内容。至少在问题中包含stacktrace,并在代码中标记重要的行号。另外,尝试先简化代码(参见SSCC)。
- +1有一个很好的例子,包括遍历stacktrace;重要的是要说明为什么读取它对于调试NPE很重要。(为什么我们总是在有人发布关于错误的问题时寻找stacktrace)
- 你提到调试……那是怎么工作的?我研究这个话题已经有一段时间了,但是什么也找不到。我相信像你这样一个了不起的老师能马上教给我!非常感谢!-)
- @Ruchirbaronia调试器允许您一行一行地遍历程序,以查看调用了哪些方法以及如何更改变量。IDE应该有一些工具来实现这一点。例如,请参见vogella.com/tutorials/eclipsedebugging/article.html。
- @Ruchirbaronia在StackTrace中看到的任何NullPointerException周围的方法上设置断点,并根据预期检查变量的值。如果知道变量不应该为空,那么可以在任何更改该值的代码周围设置断点。还有一些条件断点,您可以使用它们来告诉您值何时更改。
- 将字符串对象设置为空字符串作为其默认值被认为是一种糟糕的做法。
- 我还建议使用静态分析工具,如findbugs en.m.wikipedia.org/wiki/findbugs
- 使用非空注释可以帮助捕获它。
- "at test.main"表示我们在Test类的main方法中。
- "Test.java:4"给出了类的源文件名,它告诉我们发生的语句在文件的第4行。
如果您对上面文件中的行进行计数,那么第4行就是我用"here"注释标记的行。好的。
注意,在一个更复杂的例子中,NPE堆栈跟踪中会有很多行。但是你可以确定第二行(第一个"at"行)会告诉你NPE在哪里。好的。
简而言之,堆栈跟踪将明确地告诉我们程序的哪个语句抛出了NPE。好的。
1-不完全正确。有一些东西叫做嵌套异常…好的。问题:如何在代码中跟踪NPE异常的原因?
这是最困难的部分。简短的答案是将逻辑推理应用于堆栈跟踪、源代码和相关API文档提供的证据。好的。
让我们先用上面的简单例子来说明。我们首先查看堆栈跟踪告诉我们NPE发生的位置的行:好的。
1
| int length = foo.length(); // HERE |
那怎么会造成不良后果呢?好的。
事实上,只有一种方法:只有当foo的值为null时,才会发生这种情况。然后我们尝试在null上运行length()方法,然后……砰!好的。
但是(我听到你说)如果NPE是在length()方法调用中抛出的呢?好的。
好吧,如果发生这种情况,堆栈跟踪看起来会有所不同。第一行"at"表示在java.lang.String类的某一行中抛出了异常,而Test.java的第4行将是第二行"at"。好的。
那么,那个null是从哪里来的呢?在这种情况下,这是显而易见的,而且很明显我们需要做什么来修复它。(为foo指定一个非空值。)好的。
好吧,让我们尝试一个稍微复杂一点的例子。这需要一些逻辑推理。好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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 Test
Exception in thread "main" java. lang. NullPointerException
at Test. test(Test. java:6)
at Test. main(Test. java:10)
$ |
现在我们有两条"at"线。第一个是这行:好的。
1
| return args[pos].length(); |
第二条是这条线:好的。
1
| int length = test(foo, 1); |
看第一行,这怎么会造成不良事件呢?有两种方法:好的。
- 如果bar的值是null,那么bar[pos]将抛出一个NPE。
- 如果bar[pos]的值是null,那么对其调用length()将抛出一个NPE。
接下来,我们需要弄清楚哪些场景解释了实际发生的情况。我们将从探索第一个:好的。
江户十一〔九〕是从哪里来的?它是test方法调用的参数,如果我们看看test是如何调用的,我们可以看到它来自foo静态变量。此外,我们可以清楚地看到,我们将foo初始化为非空值。这足以暂时否定这一解释。(理论上,还有别的东西可以把foo改成null……但这不是在这里发生的。)好的。
那么第二种情况呢?好吧,我们可以看到pos是1,这意味着foo[1]必须是null。有可能吗?好的。
的确如此!这就是问题所在。当我们这样初始化时:好的。
我们分配一个String[],其中有两个元素初始化为null。之后,我们没有改变foo的内容。因此,foo[1]仍然是null。好的。好啊。问题:什么导致了NullPointerException(NPE)?
正如你应该知道的,Java类型被划分为原始类型(EDCOX1,3,4,EDCOX1,等等)和引用类型。Java中的引用类型允许您使用特殊值EDCOX1(5),这是Java方式的"无对象"。好的。
每当你的程序试图使用一个null时,就会在运行时抛出一个NullPointerException,就好像它是一个真正的引用一样。例如,如果编写此命令:好的。
1 2 3 4 5 6
| public class Test {
public static void main (String[] args ) {
String foo = null;
int length = foo. length(); // HERE
}
} |
标记为"here"的语句将尝试在null引用上运行length()方法,这将抛出NullPointerException。好的。
有许多方法可以使用null值,这将导致NullPointerException。事实上,在不引起NPE的情况下,您可以对null进行的唯一操作是:好的。
- 将它赋给一个引用变量或从引用变量中读取它,
- 将其分配给数组元素或从数组元素中读取(前提是数组引用本身不为空!),
- 将其作为参数传递或作为结果返回,或
- 使用==或!=操作符或instanceof对其进行测试。
问题:如何读取NPE StackTrace?
假设我编译并运行上面的程序:好的。
第一条观察:编译成功!程序中的问题不是编译错误。这是一个运行时错误。(某些IDE可能会警告您的程序总是抛出异常…但是标准的javac编译器没有。)好的。
第二个观察:当我运行程序时,它输出两行"GobbledyGook"。错了!!那可不是狼吞虎咽的蠢货。这是一个stacktrace…它提供了重要的信息,如果您花时间仔细阅读,它将帮助您跟踪代码中的错误。好的。
那么让我们看看它是怎么说的:好的。
堆栈跟踪的第一行告诉您许多事情:好的。
- 它告诉您抛出异常的Java线程的名称。对于具有一个线程的简单程序(如这个线程),它将是"main"。我们继续……
- 它告诉您抛出的异常的全名,即java.lang.NullPointerException。
- 如果异常有关联的错误消息,则将在异常名称之后输出。在这方面,NullPointerException是不常见的,因为它很少有错误消息。
第二行是诊断NPE最重要的一行。好的。
1
| at Test.main(Test.java:4) |
这告诉我们很多事情:好的。
就像你试图访问的对象是null。请考虑以下示例:
此时,您刚刚声明了该对象,但没有初始化或实例化。当您试图访问其中的任何属性或方法时,它将抛出有意义的NullPointerException。
请参见下面的示例:
1 2
| String a = null;
System. out. println(a. toString()); // NullPointerException will be thrown |
- 如果我们给system.out.println(a.length());//将抛出nullpointerException,为了跳过这个问题,我们可以使用try catch块来处理。谢谢您
当应用程序尝试在需要对象的情况下使用空值时,会引发空指针异常。这些包括:
调用null对象的实例方法。
访问或修改null对象的字段。
把EDOCX1的长度(0)当作一个数组。
访问或修改EDOCX1的插槽(0),就好像它是一个数组一样。
抛出null,就好像它是一个可丢弃的值。
应用程序应该抛出此类的实例,以指示其他非法使用null对象。
参考:http://docs.oracle.com/javase/8/docs/api/java/lang/nullpointerexception.html
- 让它简单,这样的答案,如果你认为正确的add this to an未初始化的属性的存取对象
- "埃米利亚诺-简单的accessing does not an an NPE initialized属性的原因。它是什么你>>,<<给未初始化的属性value with the that the NPE的原因。
- This is from docs.oracle.com javase / 8 /文档/ / / / / Java API郎& hellip;。1换quoting没有参考。
- 如果你想要更多的案例:(1)使用nullas the of a synchronized目标块,2)使用目标nullas the of a switch,null和装箱。
null指针是指不指向任何地方的指针。当您取消对指针p的引用时,您会说"把存储在"p"中的位置的数据给我"。当p为空指针时,存储在p中的位置为nowhere时,您会说"把位置‘无处’的数据给我"。显然,它不能这样做,所以它抛出了一个NULL pointer exception。
一般来说,这是因为有些东西没有正确初始化。
- 我们正在创建数据库吗?--EDCOX1→0〕在Java中被写为EDCOX1→0。这是个区分大小写的问题。
- "一个空指针是一个指向任何地方的指针,"我不同意。空指针不指向任何地方,而是指向空值。
- @Thereachx101空指针和指向空值的指针是不同的东西-空指针不指向空值。假设您有一个指向指针的指针:指针A指向指针B,指针B为空。在这种情况下,指针A指向一个空值,而指针B是一个空指针。
已经有很多解释来解释它是如何发生的以及如何修复它的,但是您还应该遵循最佳实践来避免NullPointerException。
参见:最佳实践的良好列表
我想补充一点,非常重要的是,充分利用final修饰语。在Java中使用"最终"修饰符
总结:
使用final修饰符强制良好的初始化。
避免在方法中返回空值,例如在适用时返回空集合。
使用注释@NotNull和@Nullable
快速失败并使用断言以避免空对象在不应为空时在整个应用程序中传播。
先用已知对象的等号:if("knownObject".equals(unknownObject)。
比起toString(),更喜欢valueOf()。
使用空安全StringUtils方法StringUtils.isEmpty(null)方法。
- 在J2EE项目中,nullpointer异常非常常见。有些情况下,引用变量的值为空。因此,应正确检查变量的初始化。在条件语句期间,应始终检查标志或引用是否包含空值,如:-if(标志!=0)使用标志的UR代码
- 值得一提的是,一些IDE(例如Eclipse)基于可定制的注释(如上文所列的@Nullable)提供自动零位分析,并警告潜在的错误。也可以根据现有的代码结构推断和生成此类注释(例如,intellij可以这样做)。
- 首先,在使用一个可以为空的对象之前,您应该使用if (obj==null)检查它是否为空。如果它为空,那么您还应该编写代码来处理它。
- 在IMO中,最好尽量避免在方法中返回空对象,在不允许空输入参数的情况下使用注释,以便根据约定减少代码中的&180;if(obj==null)&180;并提高代码的可读性。
- 读这个…在你接受这些"最佳实践"作为事实之前:satisfice.com/blog/archives/27
- 空指针是指不指向任何地方或空引用的指针。当您取消对指针p的引用时,您会说"将存储在"p"中的位置的数据给我"。当p是一个空指针时,存储在p中的位置就不在任何地方,你说的是"把"不在"位置的数据给我"。显然它不能这样做,所以它抛出了一个空指针异常。一般来说,这是因为有些东西没有正确初始化。public void dosomething(object obj)//检查空if(obj!=空)//做点什么别的//做点别的
- 我还使用finalon参数作为实例(它指向的地方)应该大部分(99.999%的所有参数)不被更改。当然,您仍然可以更改值。
- 标记(临时)字段dOCx1〔0〕表示不能重新分配。如何才能产生/避免NullPointerException?->结论:这完全是一个偏离主题的话题。
- 您应该像数据类型.valueof(一些变量/视图)一样进行写入
空指针异常是一个指示器,您正在使用一个对象而没有初始化它。
例如,下面是一个学生班,将在我们的代码中使用它。
1 2 3 4 5 6 7 8 9 10 11 12
| public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
} |
下面的代码给出了一个空指针异常。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class School {
Student obj_Student ;
public School () {
try {
obj_Student. getId();
}
catch(Exception e ) {
System. out. println("Null Pointer");
}
}
} |
因为您使用的是Obj_Student,但是忘记了像在正确的代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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");
}
}
} |
- 这是我的好实例,可以问什么问题,不adds to the the other已经覆盖模式在回答?
- 它是不适当的使用简单的to the word"初始化"在这里。the example is shown你事实",它是initialized"和initialized与零。for初始化变量,编译器会complain to You。
- 安安的NPE indicator that may be using一场你是未初始化的。may be an indicator that /你是做其他的事情。单身的原因oversimplifying does not help这样一个NPE解决问题……if this is not the actual的原因之一。
在Java中,一切都以类的形式出现。
如果要使用任何对象,则有两个阶段:
申报
初始化
例子:
- 声明:Object a;。
- 初始化:a=new Object();。
同样适用于阵列概念
- 声明:Item i[]=new Item[5];。
- 初始化:i[0]=new Item();。
如果不提供初始化部分,则出现NullPointerException。
- 在原始变量declaring,such as does not an int,在西安创建Java对象。
- 在为NullPointerException often occurs when Calling for example method of an instance。如果你宣布,but does not make a reference to any审为NullPointerException EN点会发生,当你呼叫它的方法。yourclass such as:ref = null;/或ref = anotherref;//but has not any anotherref角ref.somemethod(审);//EN会把空指针异常。式中:generally恩* before the method is called the参考,确定是否是空的。yourref such as:if(!yourref.somemethod=null){();}
- 例外:such as或使用尝试捕捉:捕捉yourref.somemethod();} {(为NullPointerException){ } /待办事项
在Java中,所有声明的变量实际上是对对象(或基元)的引用,而不是对象本身。
当您尝试执行一个对象方法时,引用会要求活动对象执行该方法。但如果引用引用的是空值(Nothing、Zero、Void、Nada),则无法执行该方法。然后运行时通过抛出NullPointerException让您知道这一点。
您的引用是"指向"空值,因此是"空->指针"。
对象位于虚拟机内存空间中,访问它的唯一方法是使用this引用。举个例子:
1 2 3 4 5 6 7 8 9
| public class Some {
private int id;
public int getId(){
return this.id;
}
public setId( int newId ) {
this.id = newId;
}
} |
在你的代码中的另一个地方:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Some reference = new Some (); // Point to a new object of type Some()
Some otherReference = null; // Initiallly this points to NULL
reference. setId( 1 ); // Execute setId method, now private var id is 1
System. out. println( reference. getId() ); // Prints 1 to the console
otherReference = 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 happen
System. out. println( reference. getId() ); // :S Throws NullPointerException because"reference" is pointing to NULL remember... |
这是需要知道的一件重要事情——当不再有对象的引用(在上面的例子中,当reference和otherReference都指向空值时),那么对象就是"不可访问的"。我们无法使用它,所以这个对象已经准备好被垃圾收集,在某个时候,虚拟机将释放这个对象使用的内存,并分配另一个。
当声明一个对象数组,然后立即尝试取消对其中的元素的引用时,会出现另一个NullPointerException的情况。
如果比较顺序相反,则可以避免这种特殊的NPE;即,在有保证的非空对象上使用.equals。
数组中的所有元素都初始化为它们的公共初始值;对于任何类型的对象数组,这意味着所有元素都是null。
在访问或取消引用数组中的元素之前,必须对它们进行初始化。
1 2 3 4 5
| String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase ="Bird";
for(String phrase : phrases ) {
System. out. println(phrase. equals(keyPhrase ));
} |
- 在实例级别(而不是类级别)对未初始化的对象执行的操作将导致NullPointerException。操作必须是特定于实例的。如果操作处于类级别,并表示对未初始化的对象调用静态方法,则不会引发NullPointerException异常。即使是基本包装类对象也会引发NullPointerException。
- 1。NullPointerException是一个RuntimeException,这意味着当程序运行时将出现,而不是在编译时出现。:(,但大多数IDE都帮助您发现这一点。2。最小化在赋值语句中使用关键字"null"。:)引用URL:
- @Tomj0101我完全不清楚你为什么这么说…但到第二点,在Optional之前的模式是返回空值。关键字很好。知道如何防范是至关重要的。这提供了一个常见的事件和缓解它的方法。
- NullPointerException是一个运行时异常,建议不要捕获它,而是避免它。
- @肖木:我建议什么时候抓到它?