当前位置: 首页 > 面试题库 >

匿名内部类中Java局部变量的可见性-为什么需要'final'关键字?

富辰阳
2023-03-14
问题内容

我不明白为什么我不能总是从“侦听器”或“处理程序”内部访问变量。

这是我的代码:

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是一个匿名内部类,我认为这很清楚:

本地类绝对可以引用实例变量。它们无法引用非最终局部变量的原因是,方法返回后,局部类实例可以保留在内存中。当该方法返回时,局部变量超出范围,因此需要它们的副本。如果变量不是最终变量,则该方法中变量的副本可能会更改,而本地类中的副本不会更改,因此它们将不同步。

匿名内部类需要最终变量,因为它们在Java中的实现方式。匿名内部类(AIC)通过创建一个私有实例字段来使用局部变量,该实例实例字段保存该局部变量的值的副本。内部类实际上并不使用局部变量,而是一个副本。在这一点上应该很明显的是,如果原始值或复制的值发生更改,则可能发生“错误的事情”。将会出现一些意外的数据同步问题。为了避免此类问题,Java要求您将AIC将使用的局部变量标记为最终变量(即不可更改)。这样可以确保内部类的局部变量副本始终与实际值匹配。



 类似资料:
  • 问题内容: 如何在我的匿名内部子类中获取传递给此方法的值? 我收到此错误: 无法在以其他方法定义的内部类中引用非最终变量userID 我很确定我不能将其赋值为final,因为它是一个未知值的变量。我听说这种语法确实以某种方式保留了作用域,所以我认为必须有一个我不太了解的语法技巧。 问题答案: 当然,您可以将其分配为final-只需将该关键字放入参数的声明中即可: 我不确定这是一个未知值的变量是什么

  • 我得到了一个问题,对内部类的局部变量访问需要声明为final。从方法createGrids()->“”中,i是一个需要声明为final的局部变量。我不知道为什么,我在字段中添加了final,但它并不起作用。 //略

  • 问题内容: 我想使用a 对图进行拓扑排序。为简便起见,我想为比较器使用匿名内部类。但是,我需要访问该图才能确定我正在查看的节点的程度。这可能吗? 正确的代码 问题答案: 是的,使其最终化: 有关最终关键字,请参见最终词: 匿名本地课程 第二种情况涉及最终变量,实际上是语言语义所规定的。在这种情况下,除非声明为final,否则Java编译器将不允许您使用变量。这种情况出现在闭包(也称为匿名本地类)中

  • 问题内容: 我目前正在与Sierra&Bates一起准备S(O)CJP。 关于内部类(局部或匿名方法),他们说我们无法访问局部变量,因为它们在类驻留在堆上时仍位于堆栈中,并且可以由方法返回,然后尝试访问这些变量由于该方法已结束,因此它们已在堆栈中,但已不存在… 众所周知,我们可以使用final关键字来绕开它。这就是他们在书中所说的,但是他们并没有真正解释final关键字的作用……据我所知,在方法局

  • 问题内容: 如果省略,则会看到错误“ 无法在用其他方法定义的内部类中引用非最终变量jtfContent ”。 为什么匿名内部类必须要求外部类实例变量为final才能访问它? 问题答案: 首先,让我们放松一下,请放下那把枪。 好。现在,语言坚持的原因是它作弊是为了让你的内部类函数可以访问他们渴望的局部变量。运行时复制本地执行上下文(以及其他适当的内容),因此它坚持要求你进行所有操作,final以使事

  • 问题内容: 在以下代码段中: 是否有关键字从内部类引用外部类?基本上我想做的是或类似的东西,但是似乎什么也找不到。 问题答案: 通常,你用于引用外部类的封闭实例。 在你的例子中