1

在我的主要课程中:

public class Main{
    public static void main(String[] args) {
    //some code
    final int number = 0;


    numberLabel.setText(number);

    Timer t = new Timer();

        t.scheduleAtFixedRate(new TimerTask(){
           public void run(){
           //elapsed time
               number = number + 1;
           }

        }, 1000, 1000);

   }

}

我正在使用最终的 int 变量number将经过的时间显示到标签numberLabel中。但是我无法访问计时器内的最终 int 变量,错误说:

“无法分配最终的局部变量编号,因为它是在封闭类型中定义的”

我知道我可以在 run() 中使用 numberLabel.setText() 直接更新标签,但是我需要 number 变量来计算一些时间。如何更新数字变量?谢谢

4

2 回答 2

4

您应该将 number 声明为类字段,而不是方法的局部变量。这样它就不需要是最终的并且可以在匿名内部类中使用。

我建议不要将其设为静态,并且不要在静态环境中使用 Timer,而是在实例世界中使用。

public class Main{
    private int number = 0;

    public void someNonStaticMethod() {
      //some code
      // final int number = 0;

      numberLabel.setText(number);
      Timer t = new Timer();
      t.scheduleAtFixedRate(new TimerTask(){
           public void run(){
           //elapsed time
               number = number + 1;
           }

      }, 1000, 1000);
   }
}

顺便说一句,您的使用numberLabel.setText(...)表明这将在 Swing GUI 中使用。如果是这样,那么不要使用 java.util.Timer,而应该使用 javax.swing.Timer 或 Swing Timer。

public class Main2 {
  public static final int TIMER_DELAY = 1000;
  private int number = 0;

  public void someMethod() {
    numberLabel.setText(String.valueOf(number));
    new javax.swing.Timer(TIMER_DELAY, new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        number++;
        numberLabel.setText(String.valueOf(number));
      }
    }).start();
  }
}

同样,如果这是一个 Swing 应用程序(你没有说),那么由 Timer 重复运行的代码在 Swing 事件线程 EDT(事件调度线程)上运行是至关重要的。java.util.Timer 不执行此操作,而 Swing Timer 执行此操作。

于 2013-10-13T12:14:51.957 回答
1

您不能更新声明的字段final。另一方面,您需要将其声明为 final 才能在内部类中使用它。当你在做多线程时,你可能想用 afinal java.util.concurrent.atomic.AtomicInteger number;代替。这允许通过set()TimerTask的以及基本的线程安全进行分配。

于 2013-10-13T12:14:22.347 回答