我不明白为什么我不能总是从“监听器”或“处理程序”中访问变量。
这是我的代码:
Button btnDownload = new Button(myparent, SWT.NONE);
btnDownload.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
btnDownload.setEnabled(false); // I CAN'T
}
});
唯一的方法是使用 final
关键字声明它:
final Button btnDownload = new Button(myparent, SWT.NONE);
为什么我需要声明一个变量 final 才能在事件中获得访问权限?
最佳答案
您的 SelectionAdapter
是一个匿名内部类,我认为这很清楚:
本地类绝对可以引用实例变量。它们不能引用非 final 局部变量的原因是因为局部类实例在方法返回后可以保留在内存中。当方法返回时,局部变量超出范围,因此需要它们的副本。如果变量不是最终的,那么方法中的变量副本可能会改变,而本地类中的副本不会改变,所以它们会不同步。
匿名内部类需要 final 变量,因为它们是在 Java 中实现的。匿名内部类 (AIC) 通过创建一个私有(private)实例字段来使用局部变量,该字段保存局部变量值的副本。内部类实际上并没有使用局部变量,而是一个副本。在这一点上应该很明显,如果原始值或复制值发生变化,就会发生“坏事”™;会有一些意想不到的数据同步问题。为了防止此类问题,Java 要求您将 AIC 将使用的局部变量标记为最终变量(即不可更改)。这保证了内部类的局部变量副本将始终与实际值匹配。
关于匿名内部类中的 Java 局部变量可见性 - 为什么需要 'final' 关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7423028/