我有一个设置变量的静态方法:
static String[] playersNames;
public static void setParameters(String[] players) {
playersNames = players;
}
然后我有一个静态块:
static {
JRadioButton option;
ButtonGroup group = new ButtonGroup();
// Wright a short explanation of what the user should do.
partnerSelectionPanel.add(new JLabel("Pleas select a partner:"));
// Generate radio-buttons corresponding to the options available to the player.
// Bellow is the problematic line causing the null pointer exception:
for (String playerName: playersNames) {
final String pn = playerName;
option = new JRadioButton(playerName, false);
option.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent evt) {
partner = pn;
}
});
partnerSelectionPanel.add(option);
group.add(option);
}
partnerSelectionPanel.add(label);
// Add the "Submit" button to the end of the "form".
JButton submitButton = new JButton("Submit");
submitButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent evt) {
partnerSelected();
}
});
partnerSelectionPanel.add(submitButton);
}
编译器不会抱怨什么,但是当我尝试执行代码时,我遇到了问题。在这个地方SelectPartnerGUI.setParameters(players);
我有:
线程“main”中的异常 java.lang.ExceptionInitializerError。
这是由于这个地方for (String playerName: playersNames)
的java.lang.NullpointerException引起的。
我的程序没有看到palyersNames吗?
我第一次以这种方式引用课程:SelectPartnerGUI.setParameters(players);
。在我的课堂上,我在有问题的静态块之前有setParameters
方法。那么,为什么在调用setParameters
方法之前调用此静态块?
答案 0 :(得分:7)
任何静态初始化程序块在加载类后立即执行。在静态初始化程序运行之前,您无法在类上调用方法。您需要在静态初始化程序块本身中设置playersNames
。请记住,它们按照代码中出现的顺序执行。更好的方法IMO是重写整个事物并利用构造函数构建类。
更新:根据您的修改:
我第一次以这种方式引用课程:
SelectPartnerGUI.setParameters(players);
。在我的课堂上,我在有问题的静态块之前有setParameters
方法。那么,为什么在调用setParameters
方法之前调用此静态块?
一旦加载了类,就会调用静态块。当JVM第一次遇到SelectPartnerGUI
时,就会发生这种情况。在JVM加载之前,您不能在类上调用任何(静态)方法。这就像你在开启发动机之前不能开车一样。
答案 1 :(得分:2)
这是合乎逻辑的,因为变量未初始化
每当第一次访问类时,都会执行static
块。
因此,此时静态变量仍为null
。
要解决此问题 - 要么设置变量的初始值,要么(可能更好地考虑用例) - 将static
初始化块更改为static
方法并仅在您拥有之后调用它叫做二传手。
答案 2 :(得分:2)
请记住,在java中,如果你有一个静态块,它将在构造函数之前运行。因此,您的playersName在运行静态块之后初始化。您不应该在静态块中运行这些类型的代码。
答案 3 :(得分:0)
我无法初始化静态变量playersNames
的部分。
当你到达你的循环时它是null
。您必须先为变量设置一个值(例如,通过调用setter)。
答案 4 :(得分:0)
正如所有其他人所说的那样,静态块在类加载时执行,远在你对类做任何事情之前。
除此之外,这个设计对我来说似乎有些不确定。你并没有真正看到软件开发为一系列静态块:)
我肯定会为你推荐the swing tutorial。
此外,将setParameters重命名为setPlayers以更好地反映您正在执行的操作,并在调用setPlayers时触发对partnerSelectionPanel的可能更新。除非玩家没有改变,否则你可能希望每次显示时都刷新该面板。