Java 为什么我的局部变量应该是最终的,以便从匿名类访问?
可能重复:Java 为什么我的局部变量应该是最终的,以便从匿名类访问?,java,Java,可能重复: 将局部变量声明为final以从匿名类访问它们的规则背后的原因是什么 这是因为匿名内部对象可能会保留其上下文,如果它引用的是非final变量,那么它将与不再存在的事物对话 …当 匿名类被实例化, 最终局部变量的副本 和引用的方法参数 对象的方法存储为 对象中的实例变量。这个 匿名对象中的方法 类真正访问那些隐藏的 实例变量 因此,当地 变量和方法参数 通过本地 类必须声明为final 防止其值发生更改 在对象实例化之后 来自。匿名类是一个单独的类。它无法访问方法内部的控制流。如果要在
将局部变量声明为final以从匿名类访问它们的规则背后的原因是什么 这是因为匿名内部对象可能会保留其上下文,如果它引用的是非
final
变量,那么它将与不再存在的事物对话
…当
匿名类被实例化,
最终局部变量的副本
和引用的方法参数
对象的方法存储为
对象中的实例变量。这个
匿名对象中的方法
类真正访问那些隐藏的
实例变量
因此,当地
变量和方法参数
通过本地
类必须声明为final
防止其值发生更改
在对象实例化之后
来自。匿名类是一个单独的类。它无法访问方法内部的控制流。如果要在匿名类中重新分配变量,实际上只会重新分配匿名类的变量副本。这将是非常容易出错的,因此设计选择是为了使它成为一个错误
如果要解决此问题,请使用。当您从匿名类访问
final
变量时,编译器会将其值秘密复制到匿名类的成员变量中。例如:
Runnable foo() {
final int x = 42;
return new Runnable() {
void run() {
System.out.writeln(x);
}
};
}
变成:
// the actual name is generally illegal in normal java syntax
class internal_Runnable implements Runnable {
final int x;
internal_Runnable(int _x) { x = _x; }
void run() {
System.out.writeln(x);
}
}
void foo() {
final x = 42;
return new internal_Runnable(x);
}
如果变量不是final且允许更改,则在匿名类实例中缓存的值可能会不同步。这可以通过使用闭包来避免——也就是说,一个包含所有局部变量值的对象,原始函数和新的匿名类实例都可以访问该对象。但是,这可能会导致性能下降,也许正是因为这个原因,Java语言设计人员决定不支持完全闭包。replicate of(但没有更多接近票数)