清楚地初始化字段抛出NullPointerException

时间:2013-05-11 17:14:42

标签: java swing

我讨厌问这个,但是我得到了一个带有两个全局变量weakAcidweakBase的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

}

}

2 个答案:

答案 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的初始化。