NullPointerException是当您尝试使用指向内存中空位置的引用(null)时发生的异常,就好像它引用了一个对象一样。
当我们声明引用变量(即对象)时,实际上是在创建指向对象的指针。考虑以下代码,您可以在其中声明基本类型的整型变量x:
int x; x = 10;
在此示例中,变量x是一个整型变量,Java将为您初始化为0。当您在第二行中将其分配给10时,值10将被写入x指向的内存中。
但是,当您尝试声明引用类型时会发生不同的事情。请使用以下代码:
Integer num; num = new Integer(10);
第一行声明了一个名为的变量num,但它不包含原始值。相反,它包含一个指针(因为类型Integer是一个引用类型)。既然你还没有说什么指向Java,它将它设置为null,意思是“ 我什么都没有指向”。
在第二行中,new关键字用于实例化(或创建)Integer类型的对象,并为指针变量num分配此对象。您现在可以使用解引用运算符.(点)来引用对象。
在当你声明了一个变量,但是没有创建一个对象,会发生Exception。如果您在创建num对象之前尝试取消引用,则会得到一个NullPointerException。在最琐碎的情况下,编译器将捕获问题并让您知道“num可能尚未初始化”,但有时您编写的代码不会直接创建对象。
例如,您可能使用了如下的方法:
public void doSomething(SomeObject obj) { //do something to obj }
在这种情况下,您没有创建对象obj,而是假设它是在doSomething调用方法之前创建的。如果你像这样调用方法:
doSomething(null);
在这种情况下obj为null。如果该方法旨在对传入的对象执行某些操作,则需要抛出异常,因为NullPointerException它是程序错误,程序员将需要该信息用于调试的目的。
或者,可能存在这样的情况:该方法的目的不仅仅是对传入的对象进行操作,因此可以接受空参数。在这种情况下,您需要检查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 } }
我如何解决它?
所以你有一个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(); } }
标识空值
第一步是确切地确定导致异常的值。为此,我们需要做一些调试。学习阅读堆栈跟踪很重要。这将显示抛出异常的位置:
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是null,并且调用length方法会抛出异常。我们可以看到程序在s.length()方法中删除时停止抛出异常。
追踪这些值来自哪里
接下来检查此值的来源。按照该方法的调用者,我们可以看到,s与传递printString(name)的print()方法,并this.name为空。
跟踪应设置这些值的位置
在哪里this.name设置?在setName(String)方法中。通过一些更多的调试,我们可以看到根本没有调用此方法。如果调用该方法,请确保检查调用这些方法的顺序,并且在print方法之后不调用set 方法。
这足以为我们提供一个解决方案:在调用printer.setName()之前添加调用printer.print()。
其他修正
该变量可以具有默认值(并且setName可以防止将其设置为null):
private String name = "";
任一print或printString方法可以检查空,例如:
printString((name == null) ? "" : name);
或者您可以设计如下所示的类,以便name 始终具有非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(); } }
到此这篇关于详解Java中NullPointerException异常的原因详解以及解决方法的文章就介绍到这了,更多相关Java NullPointerException异常内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!
本文向大家介绍java 出现NullPointerException的原因及解决办法,包括了java 出现NullPointerException的原因及解决办法的使用技巧和注意事项,需要的朋友参考一下 java 出现NullPointerException的原因及解决办法 日常开发过程中,最常见的异常莫过于NullPointerException,之前的时候,只是知道去找到报错的位置,然后去解决
本文向大家介绍Python中异常重试的解决方案详解,包括了Python中异常重试的解决方案详解的使用技巧和注意事项,需要的朋友参考一下 前言 大家在做数据抓取的时候,经常遇到由于网络问题导致的程序保存,先前只是记录了错误内容,并对错误内容进行后期处理。 原先的流程: 改进后的流程: 最近发现的新的解决方案:retrying retrying是一个 Python的重试包,可以用来自动重试一些可能运行
本文向大家介绍详解js跨域原理以及2种解决方案,包括了详解js跨域原理以及2种解决方案的使用技巧和注意事项,需要的朋友参考一下 1.什么是跨域 我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题. 跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说,同源策略是指一段脚本只能读取来自同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议
本文向大家介绍详谈php ip2long 出现负数的原因及解决方法,包括了详谈php ip2long 出现负数的原因及解决方法的使用技巧和注意事项,需要的朋友参考一下 php提供了ip2long与long2ip方法对ip地址处理。 1、ip2long — 将一个IPV4的字符串互联网协议转换成数字格式 int ip2long ( string $ip_address ) 参数: ip_addres
本文向大家介绍详解pandas安装若干异常及解决方案总结,包括了详解pandas安装若干异常及解决方案总结的使用技巧和注意事项,需要的朋友参考一下 在为Python安装第三方工具pandas出现了若干问题。 当我在cmd命令环境输入pip install pandas准备安装pandas时,出现了错误提示:Microsoft Visual C++ 9.0 is required.从网上查询资料有如
Java异常简介 Java异常是Java提供的一种识别及响应错误的一致性机制。 Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。在有效使用异常的情况下,异常能清晰的回答what, where, why这3个问题:异常类型回答了“什么”被抛出,异常堆栈跟踪回答了“在哪“抛出,异常信息回答了“为什么“会抛出。 Java异常机制用到的几个关键字:try