2012-07-09 56 views
0

可能重複:
Why are only final variables accessible in anonymous class?爲什麼在將ActionListener添加到按鈕時突然需要將變量聲明爲「final」?

這是我對 「隨機數學遊戲」 的代碼,我創建類:

package RandomMathGame; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class RandomMathGame { 

    public static void main(String[] args) { 
     RandomProblemGenerator randomProblems = new RandomProblemGenerator(10); 
     final int numberProblems = 10; 
     int correctScore = 0; 
     JPanel panel = new JPanel(); 
     int answer; 
     int correctAnswer; 
     JLabel[] mathProblems = new JLabel[numberProblems]; 
     final JTextField[] mathAnswers = new JTextField[numberProblems]; 
     JLabel[] correctYesNo = new JLabel[numberProblems]; 
     final JLabel score = new JLabel(correctScore + "/10"); 
     JButton submit = new JButton("Submit"); 
     for (int i = 1; i <= numberProblems; i++) 
     { 
      final int X = randomProblems.createNumberX(); 
      final int Y = randomProblems.createNumberY(); 

      mathProblems[i] = new JLabel("" + X + " * " + Y + " = "); 
      mathAnswers[i] = new JTextField(); 


      answer = Integer.parseInt(mathAnswers[i].getText()); 
      correctAnswer = X * Y; 

      if (answer == correctAnswer) 
      { 
       correctYesNo[i] = new JLabel("Correct answer; good job!"); 
       correctScore = correctScore + 1; 
      } 
      else 
      { 
       correctYesNo[i] = new JLabel("Incorrect answer; try again!"); 

      } 
      panel.add(mathProblems[i]); 
      panel.add(mathAnswers[i]); 
      panel.add(correctYesNo[i]); 
      } 
     submit.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       score.setText("Score: " + correctScore + "/10"); 
      } 
     }); 



     panel.add(submit); 
     panel.add(score); 

     JFrame gameFrame = new JFrame(); 
     gameFrame.setTitle("Random Math Game"); 
     gameFrame.setSize(150, 150); 
     gameFrame.setVisible(true); 
     gameFrame.setContentPane(panel); 



     } 
    } 

我得到一個錯誤,在它可以被ActionListener使用之前,correctScore變量必須聲明爲final。但是,當我將correctScore設置爲最終時,它會導致各種其他錯誤。任何人都可以想出解決這個問題的方法嗎?

+3

請參閱http://stackoverflow.com/a/4732617/597657 – 2012-07-09 21:33:19

回答

3

要將局部變量傳遞給匿名類,它必須是最終的 - 這是Java語言的一部分。現在,當一個原始變量是最終的時候,你不能修改它,因此你最終得到correctScore時會遇到的問題。

一種解決方法是addActionListener呼叫之前使用臨時變量權:

final int temp = correctScore; 

,並使用該temp變量在actionPerformed方法。

請注意,當您這樣做時,任何將來的更改correctScore將而不是都體現在temp的值中。

+0

這有幫助...謝謝。 – commandrix 2012-07-09 21:43:47

0

在Java中,如果你想從一個本地類中訪問局部變量(

new ActionListener() { 
... 
... 
} 

是一個新的本地匿名類) 的變量必須聲明爲final。而不final改性劑

局部類不能訪問該封閉方法的局部變量例如:

public class Main { 
    private int b=5; 
    public void bla() { 
    int a = 5; 
    ActionListener al = new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      a = 4; // Error. a must be final 
      b = 5; // OK! 
     } 
    }; 
    } 
} 

一種可能解決問題的方法是使用任何方法之外聲明變量(B在上面的例子)

+0

正如所寫,這是不正確的。我總是訪問封閉類中的非最終變量,如下所示:ActionListener更新控件中的值。也許有一件你遺漏了,這將使這個聲明成真。 – Jay 2012-07-09 21:37:06

+0

對不起,我錯過了。類變量,可以訪問(即成員 - 私人,公共等)。包含匿名類的方法的局部變量必須是最終的。編輯我的答案 – 2012-07-09 21:43:05

-1

由於您已宣佈JLabel評分爲最終評分,因此您收到該消息。您不能使用非最終變量爲最終變量設置值。我不知道你爲什麼想讓比分最終。只要刪除最後的。

編輯:我錯過了correctScore是我第一次閱讀時的函數變量。如果你把它變成一個類變量,我認爲你的許多問題都會消失。

相關問題