java - 最终局部变量无法赋值

标签 java swing final mouselistener

我有一个座位数组,该数组有两个字符串(选定的和空的)。单击鼠标时,我想遍历数组并找到选定的座位。当我按下按钮时,它说:

The final local variable seatno cannot be assigned, since it is defined in an enclosing type.

    JButton btnContinue = new JButton("Next");
    btnContinue.addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent arg0) {

            for(int x=0;x<17;x++){
                if(anArray[x]=="selected"){

                    seatno = anArray[x];
                }
            }

            data page=new data(newfrom,newto,newtime,date2,seatno);
            page.setVisible(true);
            setVisible(false);
        }
    });
    btnContinue.setBounds(358, 227, 62, 23);
    contentPane.add(btnContinue);

最佳答案

关键是封闭类型的方法局部变量实际上复制到匿名类的实例(这是因为激活框架问题,但我不会进一步详细说明与问题无关),这就是为什么它们需要是最终的,因为嵌套类型实例中的变量不再相同。

所以,这是第一个例子:

void foo() {
    int a = 3;
    new Runnable() {
        @Override
        public void run() {
            a += 3;
        }
    };
}

这不会编译,因为您不能在匿名类的方法中引用非最终变量。当您在 a 的声明中添加 final 修饰符时,a 的值将被复制到您已定义的匿名类的创建实例中。但是,您将不能更改 a 的值,因为更改对于声明 a 的方法是不可见的。

但是,匿名类不是静态的,也就是说,它们具有对封闭实例的引用(除非声明它们的方法是静态的),您可以使用它来修改封闭实例的变量:

int a = 3;

void foo() {
    new Runnable() {
        @Override
        public void run() {
            a += 3;
        }
    };
}

这个例子确实可以编译,每次调用匿名类实例的 run() 方法时,它会将 a 增加 3。 (在这个例子中它从来没有被调用过,但这只是一个例子。)

因此,总而言之,您需要将变量 seatno 从方法局部变量转换为封闭类型的实例变量。或者,如果还没有,则需要删除 final 修饰符,因为 final 变量只能分配一次。

更新:在 Java 8 中,引入了有效最终变量的概念(参见 Java Language Specification)。然而,在这篇文章的第一个例子中,变量 a 被多次赋值,这阻止了它实际上是最终的。这意味着该示例仍然无法使用 Java 8 编译。(编译错误是“在封闭范围内定义的局部变量必须是最终的或有效的最终”)

关于java - 最终局部变量无法赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10166521/

相关文章:

java - 关于Java中声明为final的变量的一些澄清?

java - 在单元测试 Struts 2 操作时指定 session /cookies 信息?

java - Gson 帮助 - 尝试使用 Gson 获取 JSON 的第一个值(键)

java - 图形界面java插入图像空间

java - 用java制作一个基本游戏,jFrame形式与jframe

java - 为什么Java中System类声明为 "final"?

java对多个对象的方法调用

java - 如何使用从url分享图片的方法

java - 将 actionListener 添加到另一个类的 JButton

java - 为什么克隆方法不应该在正在构建的克隆上调用任何非 final方法