创建对象时Java行不可用?

创建对象时Java行不可用?,java,exception,arraylist,Java,Exception,Arraylist,尝试创建对象并将其添加到ArrayList。代码与此类似: class B{ public ArrayList<Answer> answerList = new ArrayList<Answer>(); questionList.add(new EssayQuestion()); answerList.add(new StringAnswer()); } Exception in thread "main" java.lang.NullPoin

尝试创建对象并将其添加到ArrayList。代码与此类似:

class B{
    public ArrayList<Answer> answerList = new ArrayList<Answer>();

    questionList.add(new EssayQuestion());
    answerList.add(new StringAnswer());
}

Exception in thread "main" java.lang.NullPointerException
at main.Test.createNewQuestion(Test.java:31)
at main.Survey.<init>(Survey.java:21)
at main.Test.<init>(Test.java:9)
at main.MainDriver.main(MainDriver.java:35)
答案如下:

public class StringAnswer extends Answer
{
String text;

public StringAnswer()
{
    setAnswer();

}

public StringAnswer(String text)
{
    this.text = text;
}

@Override
public void display()
{
    System.out.println(text);       
}

public String getAnswer()
{
    return text;
}

@Override
public void setAnswer()
{
    System.out.print("Enter Answer: ");
    setAnswer(kb.nextLine());
    System.out.println("");
}

public void setAnswer(String text)
{
    this.text = text;
}

}

我在这里可能有点离谱,因为我对java还比较陌生,但您是否声明了问题列表?发布的代码不显示问题列表的声明。正如我所说,我对Java还比较陌生,这是我在这个网站上的第一天。不用说,我还有很多东西需要学习。

问题可能是您正在构造函数中调用createNewQuestion。我不确定在构造类的实例时,是否保证了处理顺序。构造函数中的代码可能在answerList初始化之前执行

尝试将初始化而不是应答列表的声明移动到构造函数中

另一个可能的问题是,您的测试构造函数没有调用其超类的构造函数。构造函数的第一行应该是super

顺便说一下,您似乎对null和empty之间的区别感到困惑。如果应答列表的初始化成功完成,则它不是null,但它指向一个空列表

后续行动

我不记得超类构造函数是如何工作的。事实上,即使没有显式调用super,也会自动调用超类构造函数。如果构造函数没有显式调用超类构造函数,Java编译器会自动插入对该超类的无参数构造函数的调用。http://docs.oracle.com/javase/tutorial/java/IandI/super.html

我应该从异常的堆栈跟踪中意识到这一点。堆栈显示Test正在调用Survey,Survey随后调用Test.createNewQuestion。从您对两个构造函数非常相似的评论来看,这并不奇怪

我仍然认为问题的可能原因是事情执行的顺序。在调用调查之前,可能无法使应答列表初始化


这让我想到了我想首先给出的建议,那就是你不应该在构造函数中做这些事情,尤其是用户交互。我想说,每个类中都应该有一个名为createInstance的静态方法,该方法收集用户输入并将列表构建为局部变量,然后调用一个将这些列表作为参数的构造函数。

从您对@d_Jones的回答的评论中,我假设您有如下情况:

public class Survey{
    protected ArrayList<EssayQuestion> questionList;

    //your parent class methods;
}
public class Survey{
    protected ArrayList<EssayQuestion> questionList;

    public Survey(){
        questionList = new ArrayList<EssayQuestion>();
    }
    //your parent class methods;
}
之后,您将访问问题列表,并尝试从测试类向其中添加元素。这里的问题是,您没有实例化问题列表。这意味着questionList仍然为null,当您试图向questionList添加元素时,JVM会抛出一个NullPointerException

有几种解决方案:

解决方案1:在基类构造函数中实例化questionList。大概是这样的:

public class Survey{
    protected ArrayList<EssayQuestion> questionList;

    //your parent class methods;
}
public class Survey{
    protected ArrayList<EssayQuestion> questionList;

    public Survey(){
        questionList = new ArrayList<EssayQuestion>();
    }
    //your parent class methods;
}
现在,您可以在子类中毫无例外地访问它

解决方案2:在子类的构造函数中实例化它,或者在您第一次尝试使用它的任何地方实例化它

public class Survey{
    protected ArrayList<EssayQuestion> questionList;

    //your parent class methods;
}


public class Test extends Survey
{
  public ArrayList<Answer> answerList = new ArrayList<Answer>();

  public Test(){
    questionList = new ArrayList<EssayQuestion>(); //Option 1
  }

  public void createNewQuestion(){
    //If you've not initialized it in the constructor, try instantiating it in on first use
    if(questionList == null){ //Option 2
        questionList = new ArrayList<EssayQuestion>();
    }

    //now you can access the questionList without an exception.
    //this is because you've a valid instance of of ArrayList<EssayQuestion> to which the
    //variable questionList points to
  }
}

如果它在answerList.addnew StringAnswer崩溃;那么应答列表显然是空的。您是否尝试过使用调试器单步执行代码?如果您的代码不是太大,是否可以发布它而不是发布类似的代码。是的,anserList在添加任何内容之前为null。我将按要求发布一个更大的代码块。请共享您的StringAnswer构造函数。这太乱了。请将您的代码简化为一个简单明了的代码,即可以编译和执行的代码,以演示问题。如果您在执行此操作的过程中没有发现错误,请编辑您的问题或删除此问题并发布新问题。现在你得到的只是错误的猜测,因为这个问题是不完整的。据我所知,因为我在这个类的父类中声明了questionList,这个类扩展了它,所以我可以自由使用它。我用protected来封装它。@iaacp:所以您已经在父类中声明了questionList。但是,您在哪里实例化了它?获取NullPointerException的原因是您尚未实例化此变量。ahhh ok。所以它被宣布受保护。对不起,我在读这篇文章的第一遍就完全错过了。仍然在研究代码,看看我是否能找出什么。Sujay,questionList是在父类中声明和初始化的。我不想调用super;因为测试的构造函数非常相似,只是做了一些小的调整。所以我复制粘贴,添加了需要添加的内容。我尝试在构造函数外部声明,然后在构造函数内部初始化。同样的错误。谢谢你的回复,苏杰。问题列表已正确声明和初始化,可以很好地容纳问题。问题是w
我有一份答复清单。我尝试在构造函数中初始化它,就在构造函数之前。调试器中它的值仍显示为null。@iaacp:第31行中有什么内容-您遇到NullPointerException的地方?