2010-03-22 51 views
0

我有設置一個變量的靜態方法:爲什麼我在循環中看不到一個靜態變量?

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);我有:在線程 「主要」 java.lang.ExceptionInitializerError

例外。

它是由java.lang.NullpointerException在這個地方for (String playerName: playersNames)引起的。

我的程序沒有看到palyersNames嗎?


我第一次用這種方式提到這個類:SelectPartnerGUI.setParameters(players);。而在我的班級中,我在問題靜態塊之前有setParameters方法。那麼,爲什麼在調用setParameters方法之前調用這個靜態塊呢?

回答

7

只要類加載完成,任何靜態初始化塊都會得到執行。在靜態初始化器運行之前,你可以不可能的在一個類上調用一個方法。您需要在靜態初始化程序塊本身中設置playersNames。請記住,它們按照它們出現在代碼中的順序執行。一個更好的方法IMO將重寫整個事物並利用構造函數構造一個類。

更新:按您編輯:

我第一次引用類這樣:SelectPartnerGUI.setParameters(players);。而在我的班級中,我在問題靜態塊之前有setParameters方法。那麼,爲什麼在調用setParameters方法之前調用這個靜態塊呢?

只要加載類,就會調用靜態塊。當JVM第一次遇到SelectPartnerGUI時,就已經發生了這種情況。在JVM加載之前,您無法在類上調用任何(靜態)方法。就像在開啓發動機之前你不能開車。

+0

之前運行,我想將我的類構造爲一組靜態方法。原因是我只有一個類的實例。所以,我認爲使用構造函數和實例化類是一個牀頭的想法。但後來我意識到我在課堂的靜態領域存在問題。我不知道如何從「外部」設置這些字段的值。 – Roman 2010-03-22 12:21:11

+0

@羅曼,如果你真的只需要一個實例,你應該使用單例模式。然而,在這種情況下,應用程序模式對話框可能是您實際需要的。 – extraneon 2010-03-22 12:23:08

+2

然後*只是*只構造它的一個實例。你認爲只有一個實例並不一定意味着你需要將所有東西都變成靜態的。有些人只有一輛汽車,但這並不意味着你應該讓汽車保持靜止。順便說一句:單身模式可能不適用於此。您可以完全控制代碼。如上所述,只創建一個實例並永久重用它。就這樣。 – BalusC 2010-03-22 12:24:15

0

我不能初始化您的靜態變量playersNames的部分。

當你到達你的循環時,它是null。您必須先爲變量設置一個值(例如,通過調用setter)。

2

這是符合邏輯的,因爲變量未初始化

每當類被首次訪問執行static塊。

因此,在這一點上,靜態變量仍然是null

要解決此問題 - 要麼設置變量的初始值,要麼(可能對用例更好) - 將static初始化塊更改爲static方法,並僅在調用setter後調用它。

+0

我通過'SelectPartnerGUI.setParameters(players);'第一次問我的班。所以我認爲''setParameters'方法將被首先調用,然後將執行靜態塊(它放在'setParameters'方法之後)。 – Roman 2010-03-22 12:22:47

+0

否 - 它將在setter之前執行。 – Bozho 2010-03-22 12:37:16

+0

正如我在我的文章中回答的,靜態塊甚至在構造函數 – 2010-03-22 12:53:48

2

請記住,在java中,如果你有一個靜態塊,這將在構造函數之前運行。因此,您的playersName在您的靜態塊已運行之後初始化爲。您不應該在靜態塊中運行這些類型的代碼。

0

正如所有其他人所說的,靜態塊在類加載時執行,遠遠沒有對類做任何事情。

除此之外,設計似乎有點可疑我。你並沒有真正將軟件開發成一系列靜態模塊:)

我肯定會爲你推薦the swing tutorial

此外,將setParameters重命名爲setPlayers以更好地反映您正在做的事情,並在setPlayers被調用時觸發對partnerSelectionPanel的可能更新。除非玩家保持不變,否則每次顯示時都可能需要刷新該面板。

相關問題