3 回答
TA贡献1963条经验 获得超6个赞
NullPointerException
s是当您尝试使用指向内存中没有位置的引用(null)时发生的异常,就好像它引用了一个对象一样。在空引用上调用方法或尝试访问空引用的字段将触发a NullPointerException
。这些是最常见的,但NullPointerException
javadoc页面上列出了其他方式。
可能是我能想出的最快的示例代码来说明NullPointerException
:
public class Example { public static void main(String[] args) { Object obj = null; obj.hashCode(); }}
在内线的第一行main
,我明确地将Object
引用设置为obj
等于null
。这意味着我有一个引用,但它没有指向任何对象。之后,我尝试将引用视为通过调用其上的方法指向对象。这导致a NullPointerException
因为没有代码在引用指向的位置执行。
(这是一个技术性问题,但我认为值得一提的是:指向null的引用与指向无效内存位置的C指针不同。空指针实际上并不指向任何位置,这与指向恰好无效的位置。)
TA贡献1909条经验 获得超7个赞
什么是NullPointerException?
一个好的起点是JavaDocs。他们有这个涵盖:
当应用程序在需要对象的情况下尝试使用null时抛出。这些包括:
调用null对象的实例方法。
访问或修改空对象的字段。
将null的长度视为数组。
访问或修改null的槽,就像它是一个数组一样。
抛出null就好像它是一个Throwable值。
应用程序应抛出此类的实例以指示null对象的其他非法使用。
还有一种情况是,如果您尝试使用空引用synchronized
,那么也将根据JLS抛出此异常:
SynchronizedStatement: synchronized ( Expression ) Block
否则,如果Expression的值为null,
NullPointerException
则抛出a。
我如何解决它?
所以你有一个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(); }}
也可以看看:
我还是找不到问题
如果您尝试调试问题但仍然没有解决方案,可以发布问题以获得更多帮助,但请确保包含您目前为止尝试过的内容。至少要在问题中包含堆栈跟踪,并在代码中标记重要的行号。另外,请先尝试简化代码(请参阅SSCCE)。
- 3 回答
- 0 关注
- 443 浏览
添加回答
举报