我讨厌问这个,但是我得到了一个带有两个全局变量weakAcid
和weakBase
的NullPointerException,即使我在构造函数中清楚地初始化了这些变量。我的代码如下,错误在addComponents()方法中,并且是确切的行panel.add(weakAcid, c)
。当我调试时,我发现两个字段都无法初始化。也许帮忙?
堆栈追踪:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at java.awt.Container.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at gametype.AcidBaseGame.addComponents(AcidBaseGame.java:112)
at gametype.Game.<init>(Game.java:55)
at gametype.SolubilityGame.<init>(SolubilityGame.java:17)
at gametype.AcidBaseGame.<init>(AcidBaseGame.java:25)
at gui.GameFrame.actionPerformed(GameFrame.java:132)
public class AcidBaseGame extends SolubilityGame
{
private JButton weakAcid;
private JButton weakBase;
private int buttonIndex;
public AcidBaseGame()
{
/* hidden code to save space */
weakAcid = new JButton("Weak Acid");
weakBase = new JButton("Weak Base");
endDisplay = new JLabel();
//actionlisteners to buttons
choice1.addActionListener(this);
choice2.addActionListener(this);
weakAcid.addActionListener(this);
weakBase.addActionListener(this);
this.addComponents();
}
private void setChemical()
{
//hidden code
}
public void addComponents()
{
GridBagConstraints c = new GridBagConstraints();
//initializes fine
c.fill = GridBagConstraints.CENTER;
c.gridx = 1;
c.gridy = 0;
panel.add(chemicalLabel, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;
panel.add(choice1, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 2;
c.gridy = 1;
panel.add(choice2, c);
//error
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 2;
panel.add(weakAcid, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 2;
c.gridy = 2;
panel.add(weakBase, c);
c.fill = GridBagConstraints.CENTER;
c.gridx = 1;
c.gridy = 3;
panel.add(endDisplay, c);
}
public void determineCorrect()
{
//hidden code
}
public void actionPerformed(ActionEvent arg0)
{
//hidden code
}
}
答案 0 :(得分:4)
我的猜测:父类的构造函数调用重写的addComponents()
方法。执行此操作时,它将调用子类的addComponents()
方法,并在您初始化组件之前执行此操作。
请注意,当构造函数调用可覆盖的方法时存在危险,这就是为什么应该避免这种情况的一个原因。你甚至可能想重新评估你是否应该在这里使用继承,我猜你其实不应该这样做。
编辑:
您在评论中说明:
在早期版本中,我调用了super(),但后来我意识到在初始化之前它调用了addComponents()。我修改了我的构造函数,因此它没有使用super()。
您无需调用super()
构造函数,因为无论您是否需要它,都会自动调用它。您所能做的就是调用超类的特定构造函数,如果需要,它不会调用addComponents()。我的建议:甚至不要为这个GUI使用继承。它没有增加任何价值并带来风险。
答案 1 :(得分:1)
如果查看堆栈跟踪,请执行以下行
at gametype.AcidBaseGame.addComponents(AcidBaseGame.java:112)
at gametype.Game.<init>(Game.java:55)
表明您已在类addComponents
的构造函数中调用Game
。目前尚未进行weakAcid
的初始化。