2

我不想问这个,但是我得到了一个带有两个全局变量的 NullPointerExceptionweakAcidweakBase,即使我在构造函数中清楚地初始化了这些变量。我的代码在下面,错误在 addComponents() 方法中,并且是确切的 line 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

}

}

4

2 回答 2

4

我的猜测:父类的构造函数调用了一个被覆盖的addComponents()方法。当它执行此操作时,它将调用addComponents()子类的方法,并且会在您初始化组件之前执行此操作。

请注意,当您让构造函数调用可覆盖的方法时存在危险,这是应避免此类事情的原因之一。您甚至可能想重新评估是否应该在这里使用继承,我猜实际上您不应该。


编辑:
您在评论中声明:

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

您不必调用super()构造函数,因为无论您是否愿意,它都会自动调用。您所能做的就是调用超类的特定构造函数,如果需要,该构造函数不会调用 addComponents()。我的建议:甚至不要对这个 GUI 使用继承。它没有增加任何价值并带有风险。

于 2013-05-11T17:23:47.857 回答
1

如果您查看堆栈跟踪,以下几行

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

表明您addComponents已经在 class 的构造函数中调用Game。此时weakAcid尚未进行初始化。

于 2013-05-11T17:29:42.743 回答