Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何访问内部嵌套方法中的外部变量?_Java - Fatal编程技术网

Java 如何访问内部嵌套方法中的外部变量?

Java 如何访问内部嵌套方法中的外部变量?,java,Java,我知道这个问题可能已经存在,这是我在网站上的第一个问题,所以请容忍我。在我的情况下,我仍然很难理解这个问题 问题是:我有一个调用的方法,我有一个按钮可以改变x的值。根据x的值,我希望程序执行一些操作。下面的程序不是很完整,但你会明白: public class foo{ private void do(){ int x=0; JButton changeValue= new JButton("Change the value of x");

我知道这个问题可能已经存在,这是我在网站上的第一个问题,所以请容忍我。在我的情况下,我仍然很难理解这个问题

问题是:我有一个调用的方法,我有一个按钮可以改变x的值。根据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,我该怎么做?