当前位置: 首页 > 知识库问答 >
问题:

错误:从内部类访问局部变量a;需要宣布为最终

花阳辉
2023-03-14
class Outer
{
    void m1()
    {
        int a=12;
        class Inner
        {
            void show()
            {
                System.out.println(a);
            }
        }
        new Inner().show();
    }

}

在这里,当我编译这段代码时,我得到了一个错误,即从内部类访问局部变量a;需要宣布为最终。但这里“int a”是一个局部变量,所以为什么我们需要声明为final以便在内部类中访问。

共有2个答案

唐茂实
2023-03-14

通过将最终变量声明为数组,可以轻松解决此问题:

final int x[] = {2};

然后在您的内部类中,设置数组值(例如方法调用返回一个值):

x[0] = methodcall();

或(仅将值设置为10的示例):

x[0] = 10;
郭辉
2023-03-14

如果在内部类中使用局部变量,则需要声明它为final。对于要在这样的内部类中使用的局部变量,Java在幕后获取局部变量的副本,并将其转换为隐式实例变量,以便内部类可以访问它。因为它是一个副本,如果值发生更改,副本可能会出错。因此编译器强制您将其设置为最终版本。

请注意,在Java 8中,这是可以编译的,因为a是“有效的final”——未声明为final,但在初始化后从未更改。

JLS第8.1.3节规定:

在内部类中使用但未声明的任何局部变量、形式参数或异常参数必须声明为final或有效final(§4.12.4),否则在尝试使用时会发生编译时错误。

JLS第4.12.4节规定:

如果局部变量或方法、构造函数、lambda或异常参数未声明为final,但从未作为赋值运算符(§15.26)的左操作数或前缀或后缀递增或递减运算符(§15.14,§15.15)的操作数出现,则它实际上是final。

此外,如果以下所有条件均为真,则其声明缺少初始值设定项的局部变量实际上是最终变量:

>

  • 它不是最终的。

    每当它作为赋值运算符的左操作数出现时,它肯定是未赋值的,并且在赋值之前也不一定赋值;也就是说,它肯定是未赋值的,并且在赋值的右操作数之后也不一定赋值(§16(明确赋值))。

    它永远不会作为前缀或后缀递增或递减运算符的操作数出现。

  •  类似资料:
    • 我在中发现了一个编译错误。 代码是这样的。

    • 问题内容: 因此标题说明了一切。我的内出现编译错误。 这是代码。 问题答案: 如果您不想使其最终确定,则始终可以将其设为全局变量。

    • 问题内容: 尝试在内部类内部使用一个类的本地成员时遇到此错误。我知道将其声明为final将解决此问题,但我读到Java 8应该自动处理它,因为我将Intellij与Java 8一起使用,但它仍然无法编译。还有其他方法可以在不将其声明为final的情况下进行修复吗?谢谢。 问题答案: 我知道将其声明为final将解决此问题,但我读到Java 8应该自动处理它。 如果变量 有效地为final ,则Ja

    • 我知道这个话题听起来像是重复的,但我并不是想在这里调试这个问题,而是想绕过它。 我的程序应该做的是:对于文件夹中的每个文件,创建一个新按钮。如果您单击此按钮,请输入您刚输入的文件夹的名称。 现在我遇到的问题是,“fileName”变量需要放在final中,因为Java提供的是对象的指针,而不是值本身。但如果我这样做,则只会为任何按钮发送最后选择的文件名。

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

    • 我正在尝试让一个按钮将其值与其他变量进行比较。在onClick方法中,我收到一个错误,说变量在内部类中被访问,需要声明为最终变量。问题是变量应该被更改,所以我无法使其成为最终变量。我如何解决这个问题?这是我的代码: