Why I do not see a static variable in a loop?
I have a static method which sets a variable:
static String[] playersNames;
public static void setParameters(String[] players) {
playersNames = players;
}
Then I have a static block:
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);
}
Compiler does not complain about anything but when I try to execute the code I get problems. In this place SelectPartnerGUI.setParameters(players);
I have:
Exception in thread "main" java.lang.ExceptionInitializerError.
and it is cause by java.lang.NullpointerException at this place for (String playerName: playersNames)
.
Does my program do not see the palyersNames?
The first time I refer to the class in this way: SelectPartnerGUI.setParameters(players);
. And in my class I have the setParameters
method before the problematic static block. So, why this static block is called before the setParameters
method is called?
Any static initializer blocks get executed as soon as the class get loaded. You can impossibly call a method on a class before the static initializer runs. You'll need to set the playersNames
in the static initializer block itself. Keep in mind that they're executed in the order as they appear in the code. A better approach IMO is to rewrite the whole thing and make use of a constructor to construct a class.
Update: as per your edit:
The first time I refer to the class in this way:
SelectPartnerGUI.setParameters(players);
. And in my class I have thesetParameters
method before the problematic static block. So, why this static block is called before thesetParameters
method is called?
The static block is called as soon as the class get loaded. This already happens when the JVM encounters SelectPartnerGUI
for the first time. You cannot call any (static) methods on a class before it's loaded by JVM. It's like that you cannot drive the car before you turn on the engine .
This is logical, because the variable is not initialized
And the static
block is executed whenever the class is accessed for the first time.
Therefore, at that point, the static variable is still null
.
To solve this problem - either set an initial value of the variable, or (perhaps better regarding the usecase) - change the static
initialization block to a static
method and call it only after you have called the setter.
Remember that in java, if you have a static block, this will run before the constructor. Thus your playersName is initialized after your static block has run. You should not run these type of code in static blocks.
I can't the the part where you initialize your static variable playersNames
.
It is null
, when you reach your loop. You have to set a value for the variable first (e.g. by calling the setter).
As all the others said, static blocks are executed on class load, far before you do anything with the class.
Apart from that, the design seems a bit dubious to me. You don't really see software developed as a sequence of static blocks all that much :)
I would definitely recommend the swing tutorial for you.
Further, rename setParameters to setPlayers to better reflect what you're doing, and trigger a a possible update to the partnerSelectionPanel when setPlayers is called. You probably want to refresh that panel every time it is shown, unless players is unchanged.
精彩评论