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