如果我在方法中定义的local variable
需要使用final
,我为什么需要将Inner 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
}
为什么字符串{{1}}需要是最终常量?它是如何影响的?
答案 0 :(得分:15)
局部变量总是存在于堆栈中,当时方法已经超过所有局部变量。
但是即使方法结束后你的内部类对象也可能在堆上(假设一个实例变量保留在引用上),所以在这种情况下它不能访问你的局部变量,因为它们已经消失,除非你将它们标记为最终
答案 1 :(得分:13)
答案是两者在不同的范围内。因此,在内部类访问它之前,该变量可能会发生变化。使其成为最终阻止。
答案 2 :(得分:7)
这是因为函数内部的类实际上是局部变量的副本,因为在本地类的实例仍然存在的情况下,函数调用之后可能会销毁局部变量。要使局部变量的两个副本始终具有相同的值(使它们看起来相同),您必须将变量声明为final。
答案 3 :(得分: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,但是你将无法循环。
答案 4 :(得分:1)
您的内部课程是最终的,所以您不应该从最终实体内部修改任何内容。
答案 5 :(得分:0)
根据Java内存模型,使用final变量可确保始终初始化最终变量。 当我们尝试使用没有初始化的局部变量时,我们会收到错误 using final保证内部类初始化已使用的局部变量。