-1

尝试创建一个对象并将其添加到 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)

在调试器中,就在崩溃之前,我得到了这个: Thread.dispatchUncaughtException(Throwable) line: not available

它崩溃了 answerList.add(new StringAnswer()); ,我不知道为什么。

如果相关,questionList 会在该代码块所在的超类中初始化。我正在访问它,因为它受到保护。answerList 在本地创建。

StringAnswer 的构造函数向用户询问一个 String 并通过 Scanner 读取它。EssayQuestion() 的构造函数非常相似。

有任何想法吗?

编辑:这是根据要求提供的更多代码。是的, answerList 在初始化后和添加任何内容之前显示为 null。那是问题吗?为什么会这样?再一次,在this的父类中声明并初始化了questionList,所以不重新声明或初始化也没关系吧?

public class Test extends Survey
 {
  public ArrayList<Answer> answerList;

  public Test()
  {
            answerList = new ArrayList<Answer>();
    System.out.print("How many questions? ");
    int numQuestions = kb.nextInt();
    for (int i = 0; i < numQuestions; i++)
    {
        displayMenu();
        createNewQuestion();
    }
   }

   public void createNewQuestion()
   {
    int input = -1;
    do{
        System.out.print("Question Type: ");
        input = kb.nextInt();
        System.out.println();

        switch (input)
        {
            case 1:     questionList.add(new EssayQuestion());
                        answerList.add(new StringAnswer());
                        break;

这是StringAnswer:

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

}
4

3 回答 3

1

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

尝试将初始化(但不是声明)移动answerList到构造函数中。

另一个可能的问题是您的 Test 构造函数没有调用其超类的构造函数。构造函数的第一行应该是super();.

(顺便说一句,你似乎对和“空”之间的区别感到困惑null。如果初始化answerList成功完成,那么它不是空的,而是指向一个空列表。)

跟进

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

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

我仍然认为问题的可能原因是执行的顺序。可能没有办法在调用answerList之前进行初始化。Survey()

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

于 2012-10-27T04:53:55.277 回答
1

从您对@D_Jones 的回答的评论中,我假设您有这样的情况:

public class Survey{
    protected ArrayList<EssayQuestion> questionList;

    //your parent class methods;
}

之后,您将访问 questionList 并尝试从您的 Test 类中添加元素。这里的问题是你没有实例化 questionList。这意味着 questionList 仍然为 null,并且当您尝试向 questionList 添加元素时,JVM 会抛出 NullPointerException。

有几个解决方案:

解决方案 1:在基类构造函数中实例化 questionList。像这样的东西:

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
  }
}
于 2012-10-27T05:02:12.047 回答
0

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

于 2012-10-27T04:46:04.240 回答