【问题标题】:Why I do not see a static variable in a loop?为什么我在循环中看不到静态变量?
【发布时间】:2010-03-22 12:08:30
【问题描述】:

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

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

【问题讨论】:

    标签: java variables static visibility


    【解决方案1】:

    任何静态初始化程序块都会在类加载后立即执行。在静态初始化程序运行之前,您不可能在类上调用方法。您需要在静态初始化块本身中设置playersNames。请记住,它们是按照它们在代码中出现的顺序执行的。 IMO 更好的方法是重写整个事物并使用构造函数来构造一个类。

    更新:根据您的编辑:

    我第一次这样引用类:SelectPartnerGUI.setParameters(players);。在我的课堂上,我在有问题的静态块之前有 setParameters 方法。那么,为什么在调用setParameters 方法之前调用这个静态块呢?

    加载类后立即调用静态块。这在 JVM 第一次遇到 SelectPartnerGUI 时已经发生。在 JVM 加载类之前,您不能在类上调用任何(静态)方法。就像你不能在打开引擎之前开车。

    【讨论】:

    • 我想将我的类构建为一组静态方法。原因是我只有一个类的实例。所以,我认为使用构造函数和实例化类是一个很好的想法。但后来我意识到我对类的静态字段有问题。我不知道如何从“外部”设置这些字段的值。
    • @Roman 如果你真的只需要一个实例,你应该使用单例模式。然而,在这种情况下,应用程序模式对话框可能是您真正想要的。
    • 然后just只构造它的一个实例。您认为只有一个实例并不一定意味着您需要将所有内容都设为静态。有些人只有一辆车,但这并不意味着你应该让汽车静止。顺便说一句:单例模式在这里可能不适用。您可以完全控制代码。如前所述,只需创建它的一个实例并永远重复使用它。就是这样。
    【解决方案2】:

    这是合乎逻辑的,因为变量没有初始化

    每当第一次访问该类时,都会执行 static 块。

    因此,此时静态变量仍为null

    要解决这个问题 - 设置变量的初始值,或者(对于用例可能更好) - 将 static 初始化块更改为 static 方法并仅在调用 setter 后调用它。

    【讨论】:

    • 我第一次通过SelectPartnerGUI.setParameters(players);向我的班级提问。所以我想先调用setParameters方法,然后执行静态块(放在setParameters方法之后)。
    • 正如我在帖子中回答的那样,静态块甚至在构造函数之前运行
    【解决方案3】:

    请记住,在 java 中,如果您有一个静态块,它将在构造函数之前运行。因此,您的 playerName 您的静态块运行后被初始化。您不应该在静态块中运行这些类型的代码。

    【讨论】:

      【解决方案4】:

      我不能初始化静态变量playersNames的部分。

      当你到达你的循环时,它是null。您必须首先为变量设置一个值(例如,通过调用 setter)。

      【讨论】:

        【解决方案5】:

        正如所有其他人所说,静态块是在类加载时执行的,远在您对类执行任何操作之前。

        除此之外,这个设计对我来说似乎有点可疑。您并没有真正将软件开发为一系列静态块:)

        我绝对会为你推荐the swing tutorial

        此外,将 setParameters 重命名为 setPlayers 以更好地反映您在做什么,并在调用 setPlayers 时触发对 partnerSelectionPanel 的可能更新。您可能希望每次显示该面板时都对其进行刷新,除非玩家未更改。

        【讨论】:

          猜你喜欢
          • 2011-07-05
          • 2020-01-13
          • 2022-11-30
          • 1970-01-01
          • 1970-01-01
          • 2015-02-28
          • 2022-08-23
          • 1970-01-01
          • 2020-01-08
          相关资源
          最近更新 更多