"java.lang.NullPointerException: Attempt to invoke virtual method '...' on a null object reference



我得到了标题中描述的NullPointerException,但我不知道如何使用错误消息中的信息来调试它。我如何知道什么是null,以及常见的原因是什么?


如果您看到类似java.lang.NullPointerException: Attempt to invoke virtual method '...' on a null object reference的错误,此问题旨在帮助解决您的问题。

这也适用于以下所有类似错误:

  • java.lang.NullPointerException: Attempt to invoke interface method '...' on a null object reference
  • java.lang.NullPointerException: Attempt to read from field '...' on a null object reference
  • java.lang.NullPointerException: Attempt to read from null array
  • java.lang.NullPointerException: Attempt to get length of null array

注意:这是一个典型的自我回答问题,旨在为许多对Android上的NullPointerException有疑问的用户提供一个单一的位置,其中包含Android特定的建议

有关此问题的非Android Java版本,或有关更多信息,请参阅What is a NullPointerException,以及如何修复它

什么是NullPointerException

首先,如果您不了解null是什么,或者NullPointerException是什么意思,请查看什么是NullPointerException,以及如何修复它?。这个答案的其余部分将假设你已经阅读了那篇文章。

如何调查原因

既然你已经了解了基本知识,你需要弄清楚你的错误在哪一行。看看什么是堆栈跟踪,以及我如何使用它来调试我的应用程序错误?有关如何做到这一点的信息。

一旦你知道错误在哪一行,接下来你需要做的就是弄清楚哪个变量是空的。错误消息将帮助您完成此操作。

如果您的错误看起来像(第一个...可能是virtualinterface——哪个并不重要(:

java.lang.NullPointerException: Attempt to invoke ... method 'ReturnTypeOfMethod package.name.SomeClass.someMethod(...)' on a null object reference

这意味着您试图调用someMethod的类型为package.name.SomeClass的变量是null。它还将列出方法的参数类型(如果有的话(,其中(...)在示例中。

所以,如果你有这个代码:

MyClass myVariable = new MyClass();
String logMessage = "some other text: " + myVariable.toString() + someOtherVariable.method();

然后你得到这个错误消息:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.mypackagename.MyClass.toString()' on a null object reference

您知道myVariable为null,因为这是MyClass类型中唯一调用了toString()的变量。java.lang.String只是意味着toString()返回一个String

如果错误为Attempt to read from field...,则应用上述建议,但要查找读取字段引用(MyClass.someProperty(,而不是调用方法(MyClass.someMethod()(。

如果错误为Attempt to read from null array,则在该行中查找按索引从数组中读取的任何内容(例如,someArrayVariable[i](。

如果错误为Attempt to get length of null array,请查找对数组变量的.length调用。

常见的根本原因和修复方法

findViewById,然后在活动/片段中设置视图

一个常见的问题是在实际设置视图之前调用findViewById。例如,在成员变量声明中调用它:

public class MyActivity extends Activity {
private Button submitButton = findViewById(R.id.submitButton);
// ... rest of Activity code ...
}

或在设置ContentView:之前

public class MyActivity extends Activity {
private Button submitButton;
public void onCreate(Bundle savedInstanceState) {
submitButton = findViewById(R.id.submitButton);
setContentView(R.layout.activity_main);
}
// ... rest of Activity code ...
}

这不起作用,因为findViewById是在onCreate方法(对于Activity(或onCreateView(对于Fragment(中调用setContentView之前执行的。要解决此问题,请确保在setContentView之后调用它。对于Fragments,您可以将代码放在onViewCreated中,也可以确保在LayoutInflater.inflate调用返回的View上调用它。

布局ID/视图ID/视图不在布局中

有时问题是在给定布局中没有ID传递给findViewById的视图。仔细检查以确保您的setContentViewLayoutInflater.inflate调用具有正确的布局ID(与XML文件名匹配(,并且该布局XML文件中有一个具有该ID的视图(或<include>s的视图(。

相关内容

  • 没有找到相关文章

最新更新