3 回答
TA贡献2012条经验 获得超12个赞
NullPointerExceptions是当您尝试使用指向内存中没有位置的引用(null)时发生的异常,就好像它引用了一个对象一样。在空引用上调用方法或尝试访问空引用的字段将触发a NullPointerException。这些是最常见的,但NullPointerExceptionjavadoc页面上列出了其他方式。
可能是我能想出的最快的示例代码来说明NullPointerException:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}}在内线的第一行main,我明确地将Object引用设置为obj等于null。这意味着我有一个引用,但它没有指向任何对象。之后,我尝试将引用视为通过调用其上的方法指向对象。这导致a NullPointerException因为没有代码在引用指向的位置执行。
(这是一个技术性问题,但我认为值得一提的是:指向null的引用与指向无效内存位置的C指针不同。空指针实际上并不指向任何位置,这与指向恰好无效的位置。)
TA贡献2037条经验 获得超6个赞
什么是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)。
添加回答
举报
