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(但没有更多接近票数)