Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java添加到列表NullPointerException_Java_Arraylist - Fatal编程技术网

Java添加到列表NullPointerException

Java添加到列表NullPointerException,java,arraylist,Java,Arraylist,我已经阅读了许多关于StackOverflow的关于这类问题的其他答案,然而,我的答案与我所读的任何答案都不同 向ArrayList添加对象时遇到问题。我一直收到NullPointerException的。如您所见,我的列表已初始化,并且我正在向它提供正确类型的对象。第一次失败了。您可以在尝试添加到ArrayList之前查看我的println,println正确显示所有信息,没有任何内容为null,这些都是对象的所有属性。它尝试将该对象添加到ArrayList,并抛出NullPointerExc

我已经阅读了许多关于StackOverflow的关于这类问题的其他答案,然而,我的答案与我所读的任何答案都不同

向ArrayList添加对象时遇到问题。我一直收到NullPointerException的。如您所见,我的列表已初始化,并且我正在向它提供正确类型的对象。第一次失败了。您可以在尝试添加到ArrayList之前查看我的println,println正确显示所有信息,没有任何内容为null,这些都是对象的所有属性。它尝试将该对象添加到ArrayList,并抛出NullPointerException

请帮我整理一下,这样我就可以离开这个问题了。谢谢大家

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);
}