14

为什么我需要声明一个local variable好像finalInner class在方法中定义的需要使用它?

例子 :

class MyOuter2 {

private String x = "Outer2";

void doStuff() {
    final String y = "Hello World";

    final class MyInner {

        String z = y;

        public void seeOuter() {
            System.out.println("Outer x is "+x);
            System.out.println("Local variable is "+y);
            MyInner mi = new MyInner();
            mi.seeOuter();
        }
    }
}

}

为什么字符串y需要是最终常量?它如何影响?

4

6 回答 6

17

局部变量总是存在于堆栈中,当方法结束时,所有局部变量都消失了。

但是即使在方法结束后,您的内部类对象也可能在堆上(假设一个实例变量保留了引用),因此在这种情况下,它无法访问您的局部变量,因为它们已经消失,除非您将它们标记为 final

于 2012-04-26T17:55:15.067 回答
13

答案是两者属于不同的范围。因此,该变量可以在内部类访问它之前更改。让它最终防止这种情况发生。

于 2012-04-26T17:53:45.120 回答
8

这是因为函数内部的内部类实际上复制了局部变量,因为局部变量可能在函数调用后被销毁,而局部类的实例仍然存在。要使局部变量的两个副本始终具有相同的值(使它们看起来相同),您必须将变量声明为 final。

于 2013-07-10T20:48:00.850 回答
3

我认为这是为了防止程序员出错。这样,编译器会提醒程序员,当您离开该方法时,该变量将不再可访问。这对于循环至关重要。想象一下这段代码:

public void doStuff()
{
    InnerClass cls[] = new InnerClass[100];
    for (int i = 0; i < 100; ++i)
    {
        cls[i] = new InnerClass()
        {
            void doIt()
            {
                System.out.println(i);
            }
        };
    }
}

doIt()方法被调用时,会打印什么?i循环时更改。为了防止这种混淆,您必须将变量复制到局部变量或创建变量 final,但是您将无法循环。

于 2012-04-26T17:52:13.750 回答
1

您的内部类是最终的,因此您不应该能够从最终实体内部修改任何内容。

于 2012-04-26T17:53:47.717 回答
0

根据 Java 内存模型,使用 final 变量可以保证始终初始化 final 变量。当我们尝试在没有初始化的情况下使用局部变量时会出错。using final 保证内部类初始化使用的局部变量。

于 2014-07-20T06:27:14.510 回答