在我的代码的这一部分,我想计算用户按下按钮的次数。问题是,如果我声明该数字以计算该函数外部的点击次数,那么它根本不会执行。这是我的意思:
byte numButtonClicks = 0;
tellingIntroButton.addActionListener(e -> {
numButtonClicks ++;
System.out.println(numButtonClicks);
});
在内部声明它也不是一个选择,因为它将始终被重置。 感谢您的帮助!
答案 0 :(得分:0)
请让我知道您得到的确切错误是什么。如果numButtonClicks是局部变量,则无法在lambda函数中对捕获的局部变量进行突变。将它设为一个LongAdder类变量,该变量是原子性的,并为并发而设计。
LongAdder numButtonClicks= new LongAdder();
tellingIntroButton.addActionListener(e -> {
numButtonClicks.increment();
System.out.println(numButtonClicks);
});
答案 1 :(得分:0)
如果您有类似的东西
public class YourComponent extends JFrame { // or whatever it is you're extending
// ....
public void init() {
// ...
byte numButtonClicks = 0;
tellingIntroButton.addActionListener(e -> {
numButtonClicks ++;
System.out.println(numButtonClicks);
});
}
// ...
}
您会遇到一些问题。
在匿名内部类(例如您的动作侦听器)中使用的变量必须隐式为final。您在对另一个答案的评论中提到的例外
Exception in thread "main" java.lang.Error: Unresolved compilation problem: Local variable numButtonClicks defined in an enclosing scope must be final or effectively final
告诉您计数器变量不是最终变量
您正在使用byte
字段作为计数器。为什么不使用int
或long
?
您不能在方法内声明最终的int
或long
并将其递增。
您可以通过在班级中拥有一个成员来解决此问题,例如
public class YourComponent extends JFrame { // or whatever it is you're extending
// ....
private int numButtonClicks = 0;
public void init() {
// ...
tellingIntroButton.addActionListener(e -> {
YourComponent.this.numButtonClicks++;
System.out.println(numButtonClicks);
});
}
// ...
}
或者,就像其他答案所暗示的那样,如果并发在这里对您来说是一个问题(如果可以通过不同的线程修改计数),则可以使用诸如LongAdder
之类的java8对象。如果您沿着这条路线(LongAdder
行驶,则在方法范围内将其声明为 final 。