创建对象时Java行不可用?
尝试创建对象并将其添加到ArrayList。代码与此类似:创建对象时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
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的地方?