我有座位阵列,且所述阵列具有两个字符串(选择和空)。 在鼠标的点击,我想遍历数组,并找到选定座位。 当我按下按钮,说:
最终局部变量seatno不能被分配,因为它是在一个封闭的类型来定义。
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;
}
};
}
这不编译,因为你不能在匿名类的方法引用非最终变量。 当您添加final修饰符来声明a
,值了a
会被复制到您所定义的匿名类的创建的实例。 然而,你将不会被允许改变的值a
,因为变化将是不可见的,其中方法a
被宣布。
然而,匿名类不是静态的,也就是说,他们必须封闭实例的引用(除非他们声明的方法是静态的),你可以用它来修改封闭的实例变量:
int a = 3;
void foo() {
new Runnable() {
@Override
public void run() {
a += 3;
}
};
}
这个例子并编译,它会增加a
每次时间3 run()
匿名类的实例的方法被调用。 (在这个例子中是从来没有所谓的,但它只是一个例子。)
因此,要总结,你需要把变量转换seatno
从方法本地变量封闭类型的实例变量。 或者,如果是是,你需要删除final修饰符作为最终变量只能分配一次。
更新:在Java 8, 有效地最终变量的概念引入(见Java语言规范 )。 然而,在该文章的第一个例子中,变量a
被分配多次,这防止其有效地最后。 这意味着该实例中仍然不使用Java编译8(编译错误是“局部变量一个在封闭的范围限定必须是最后或最后有效”)
最后变量不能改变它的值(它类似于从C / C ++为const)。
你可能希望把它在一个类(当然没有final关键字)字段,而不是一个函数中的局部变量。
相反,定义一个类成员变量,你也可以使用一个可变INT来实现相同的。
void foo() {
final MutableInt a = new MutableInt(3);
new Runnable() {
@Override
public void run() {
a.add(3);
}
};
}
由于MutableInt不是原始类型(因此通过引用传递),并且可以被重新分配工作的。
最近我遇到类似的问题。 在我的情况下,它是更容易地创建最终的数组(或集合),并添加变量,我想下面的匿名类内部发生变化,这种阵列。
int a = 3;
final int[] array = new int[1];
array[0] = a;
new Runnable() {
@Override
public void run() {
array[0] += 3;
}
};
如果不知道的声明seatno
,我建议在引入新的变量mouseClicked()
是不是最终的,做同样的工作作为方法seatno
目前确实,作为变量,似乎只有这个方法的内部使用。
顺便说一句:您的大写类名( data
应该是Data
)。 会显得更加清晰。
请确保您的变量没有final
修改。
//final, can be set only when the object is created.
private final String seatno;
//no final modifier, the value can be set every time you "want"
private String seatno;
此外,比较你应该使用字符串equals
:
if(anArray[x].equals("selected"))