为什么我在循环中看不到静态变量?

时间:2010-03-22 12:08:31

标签: java variables static visibility

我有一个设置变量的静态方法:

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方法之前调用此静态块?

5 个答案:

答案 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的可能更新。除非玩家没有改变,否则你可能希望每次显示时都刷新该面板。