Java添加到列表NullPointerException
我已经阅读了许多关于StackOverflow的关于这类问题的其他答案,然而,我的答案与我所读的任何答案都不同 向ArrayList添加对象时遇到问题。我一直收到NullPointerException的。如您所见,我的列表已初始化,并且我正在向它提供正确类型的对象。第一次失败了。您可以在尝试添加到ArrayList之前查看我的println,println正确显示所有信息,没有任何内容为null,这些都是对象的所有属性。它尝试将该对象添加到ArrayList,并抛出NullPointerException 请帮我整理一下,这样我就可以离开这个问题了。谢谢大家Java添加到列表NullPointerException,java,arraylist,Java,Arraylist,我已经阅读了许多关于StackOverflow的关于这类问题的其他答案,然而,我的答案与我所读的任何答案都不同 向ArrayList添加对象时遇到问题。我一直收到NullPointerException的。如您所见,我的列表已初始化,并且我正在向它提供正确类型的对象。第一次失败了。您可以在尝试添加到ArrayList之前查看我的println,println正确显示所有信息,没有任何内容为null,这些都是对象的所有属性。它尝试将该对象添加到ArrayList,并抛出NullPointerExc
protected ArrayList units = new ArrayList<Fleet>();
public FleetParser(JSONObject json)
{
super(json);
}
@Override
public void process(JSONObject o)
{
Fleet fleet = new Fleet();
fleet.inflateFromJSON(o);
if(fleet.getUid() != null) {
System.out.println(fleet.getUid() + " " + fleet.getPuid() + " " + fleet.getShips() + " " + fleet.getName());
units.add(fleet);
}
}
初始化字段的顺序有问题。您需要知道初始化块(包括字段初始化)被调用
- 在超类的构造函数之后(在显式或隐式
调用之后,该调用始终位于构造函数的开头)super(…)
- 构造函数实际代码之前(超级(…)之后的代码)李>
class SomeClass extends BaseClass{
String field = "some value";
SomeClass(String data){ //constructor
super(data);
System.out.println(field);
}
}
将被汇编成
class SomeClass extends BaseClass{
String field = null; // initialization is moved --+
// |
SomeClass(String data){ // |
super(data); // |
field = "some value"; // here <----------------+
System.out.println(field);
}
}
输出:字段值为空
之所以发生这种情况,是因为方法
引用了TestX
类中的字段
,如前所述,它的值将设置在super()
之后,所以现在它是null
如果您不在派生类中重新声明字段
,方法
将使用基类中的字段
。所以
class Derived extends Base {
// protected String field = "bar";
public Derived() {
super();
}
public void method() {
System.out.println("value of field is "+field);
}
}
结果将是字段的值为foo
,因为字段的初始化在从构造函数调用实际代码之前完成(如前所述,字段初始化发生在super
类的构造函数之后,但在当前构造函数的实际代码之前)
您的案例与本例类似,但您没有使用字符串字段
protected ArrayList units
查看您的代码:在BaseParser
构造函数中,您正在调用initParse()
,它正在调用抽象方法process
,它使用FleetParser
(基于堆栈跟踪)中的代码,如下所示
@Override
public void process(JSONObject o)
{
//... some code
units.add(fleet);
}
而units
是在FleetParser
中重新声明的列表,并且由于控制流当前位于super(…)
无法初始化单元。在行单位中放置断点。add().您能给我们异常的堆栈跟踪吗?我认为在基类构造函数运行时,子类中的单元
没有初始化。顺便说一句,拥有两个同名字段是一个非常糟糕的主意——一个在基类中,一个在子类中。这会导致像这样令人困惑的错误。你们知道界面中的字段是静态的和最终的吗?很可能您不应该在ParserInterface
中声明ArrayList单元
和JSONObject json
,反正您已经在BaseParser
中声明了它们。另外,您不应该在构造函数(public void initParse()
)中调用非私有(或非final,或非静态)方法,因为它们是多态的,所以可以在派生类中重写。cody,Pshemo的回答是正确的,它基本上是我所说的更详细的版本。我复制它是没有意义的。我认为你应该投票接受普谢莫的回答。
class SomeClass extends BaseClass{
String field = null; // initialization is moved --+
// |
SomeClass(String data){ // |
super(data); // |
field = "some value"; // here <----------------+
System.out.println(field);
}
}
abstract class Base {
protected String field = "foo";
public abstract void method();
public Base() {
method();
}
}
class Derived extends Base {
protected String field = "bar";
public Derived() {
super();
}
public void method() {
System.out.println("value of field is "+field);
}
}
class TestX{
public static void main(String[] args) {
new Derived();
}
}
class Derived extends Base {
// protected String field = "bar";
public Derived() {
super();
}
public void method() {
System.out.println("value of field is "+field);
}
}
protected ArrayList units
@Override
public void process(JSONObject o)
{
//... some code
units.add(fleet);
}