内部类和局部变量

如果我在方法中定义的Inner class需要使用它,为什么我需要将local variable声明为final

示例:

 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(); } } } 

}

为什么String y需要是最终常量? 它是如何影响的?

答案是两者在不同的范围内。 因此,在内部类访问它之前,该变量可能会发生变化。 使它成为最终阻止。

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

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

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

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

 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,但是您将无法循环。

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

根据Java内存模型,使用final变量可确保始终初始化最终变量。 当我们尝试使用没有初始化的局部变量时,我们会收到错误 using final保证内部类初始化已使用的局部变量。