Java 如何访问内部嵌套方法中的外部变量?
我知道这个问题可能已经存在,这是我在网站上的第一个问题,所以请容忍我。在我的情况下,我仍然很难理解这个问题 问题是:我有一个调用的方法,我有一个按钮可以改变x的值。根据x的值,我希望程序执行一些操作。下面的程序不是很完整,但你会明白:Java 如何访问内部嵌套方法中的外部变量?,java,Java,我知道这个问题可能已经存在,这是我在网站上的第一个问题,所以请容忍我。在我的情况下,我仍然很难理解这个问题 问题是:我有一个调用的方法,我有一个按钮可以改变x的值。根据x的值,我希望程序执行一些操作。下面的程序不是很完整,但你会明白: public class foo{ private void do(){ int x=0; JButton changeValue= new JButton("Change the value of x");
public class foo{
private void do(){
int x=0;
JButton changeValue= new JButton("Change the value of x");
changeValue.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
x=10; //change the x value when the button is clicked
//Here the user may also change the value of x
//by inputting some other number
}
});
//Something happens depending on x
//But nothing happens here because when I get the value of x,
//it reverts back to 0.
}
}
然而,无论我在do()中声明我的x在哪里,我总是得到一个错误,告诉我内部类不能访问外部类变量,它们必须声明为final。但我不能宣布它为最终版本,因为我以后需要更改它。我试着把这些值放到一个新的类中。我还尝试将x声明为foo()的成员,但结果是x
为0或null,因为出于某种原因,一旦退出按钮单击方法,它将使x返回其旧值:0或null
我需要的是:当按下按钮时,x的值会发生变化(假设用户可以将x的值更改为其他数字),感谢您提前给出答案。您需要为
x
变量创建一个最终引用
由于它是基元类型,请创建一个类来包装它:
private static class MyX {
int x;
// + getter and setter
}
然后:
final MyX myX = new MyX(x);
JButton changeValue= new JButton("Change the value of x");
changeValue.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
myX.setX(10);
});
// get the value of MyX back if necessary
问题是:当您创建ActionListener时,您正在声明一个actionPerformed,该actionPerformed将在稍后执行。无法从actionPerformed更改x,因为x仅存在于该方法调用中
class Foo {
void doSomething() {
int x = 0; // x inside doSomething
JButton btn = new Button("Do Something");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
/*
* This does not happen now:
* it happens later.
*
* By the time this happens
* the method will have exited
* and x will be gone.
*
*/
}
});
/* That x disappears forever here.
* (Or a little bit later but basically here.)
*/
}
}
您可以将x声明为final,然后匿名类被赋予它的值,但是您想要更改它。也许你想要的是让它成为一个领域:
class Foo {
int x = 0; // x inside Foo
JButton btn = new Button("Do Something");
Foo() {
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
/* do something with x as needed */
}
});
}
}
匿名类也可以有字段:
btn.addActionListener(new ActionListener() {
int x = 0; // x inside anonymous ActionListener
@Override
public void actionPerformed(ActionEvent ae) {
/* use x only in actionPerformed */
}
});
“我也尝试过将x声明为foo()的成员,但这会导致x为0或null,因为出于某种原因,一旦退出button click方法,它会将x恢复到原来的值:0或null。”
不幸的是,这可能意味着你做错了别的事情。我不确定从您的描述和代码中可能会看到什么。例如,您正在一个方法中本地创建一个新的JButton,这似乎不寻常。除非它是“createAndShowGUI”方法之一(如世界各地所见),否则您可能会创建多个按钮、多个侦听器等。这是您的第一个问题,这一事实并不能原谅您在提问之前没有搜索这个问题。我已经搜索过了,我真的无法得到这类问题的直接答案,我尝试了其他问题中提到的答案,但似乎没有一个有效。是的,谢谢你,这确实有效…:)因此,我仍然可以通过创建最终引用来操作数据——但为什么它必须位于对象中呢?这只是一种方法吗?我以前从未使用过字段。。。这将是我清单上的下一件事,谢谢:)是的,我知道我的代码有点不寻常,但我还在学习。如果我要制作一个不需要创建多个按钮和监听器的GUI,我该怎么做?