明确初始化的字段抛出NullPointerException



我讨厌问这个,但我得到一个NullPointerException与两个全局变量weakAcidweakBase,即使我清楚地在构造函数中初始化这些变量。我的代码如下,错误是在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
}

}

我的猜测:父类的构造函数调用重写的addComponents()方法。当它这样做时,它将调用子类的addComponents()方法,并且将在您初始化组件之前这样做。

请注意,当你让构造函数调用可重写的方法时是有危险的,这就是为什么应该避免这种事情的原因之一。您甚至可能想要重新评估这里是否应该使用继承,我猜实际上您不应该使用继承。


编辑:
你在注释中声明:

在较早的版本中,我调用了super(),但后来我意识到它在初始化之前调用了addComponents()。我修改了构造函数,使其不使用super()。

你不必调用super()构造函数,因为无论你是否想要,它都会自动被调用。您所能做的就是调用父类的特定构造函数,如果需要的话,该构造函数不调用addComponents()。我的建议是:不要在GUI中使用继承。

如果查看堆栈跟踪,可以看到以下行

at gametype.AcidBaseGame.addComponents(AcidBaseGame.java:112)
at gametype.Game.<init>(Game.java:55)

显示你已经在Game类的构造函数中调用了addComponents。此时weakAcid还没有初始化

相关内容

最新更新