当我单击JavaFX中的按钮时,我想要更改变量。但是,当我尝试使用程序中的变量时,它说
从lambda内部引用的局部变量必须是final或者有效的final。
我无法使其成为最终,因为我需要更改它以便我可以使用它。我的代码看起来像这样
Button next = new Button();
next.setText("next");
next.setOnAction((ActionEvent event) -> {
currentLine++;
});
我能做些什么来解决这个问题?
答案 0 :(得分:1)
<强>概念强>
annonymous inner classes
内使用的所有局部变量应该是final or effectively final
,即状态在定义后不能更改。
<强>原因强>
内部类无法引用non final
局部变量的原因是因为本地类实例即使在方法返回后也可以保留在内存中,并且可以更改导致synchronization
问题的变量的值。
你如何克服这个?
1 - 声明一个为你完成工作并在动作处理程序中调用它的方法。
public void incrementCurrentLine() {
currentLine++;
}
后来称之为:
next.setOnAction((ActionEvent event) -> {
incrementCurrentLine();
});
2 - 将currentLine
声明为AtomicInteger。然后使用其incrementAndGet()
递增值。
AtomicInteger currentLine = new AtomicInteger(0);
稍后,您可以使用:
next.setOnAction((ActionEvent event) -> {
currentLine.incrementAndGet(); // will return the incremented value
});
3 - 你也可以声明一个自定义类,在其中声明方法并使用它们。
答案 1 :(得分:1)
您的问题有各种解决方案。除了ItachiUchiha的帖子之外,只需将变量声明为类成员,如下所示:
public class Main extends Application {
int counter = 0;
@Override
public void start(Stage primaryStage) {
try {
HBox root = new HBox();
Button button = new Button ("Increase");
button.setOnAction(e -> {
counter++;
System.out.println("counter: " + counter);
});
root.getChildren().add( button);
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}