Java作用域和生存期(内部类)



我需要解释以下代码编译失败的原因(就范围和寿命而言):

class ClassInMethod
{
   public static void main(String[] args)
   {
      int local = 1;
      class Inner
      {
         public void method()
         {
             System.out.println(local);
         }
      }
   }
}

我认为是因为:内部类中使用但未声明的任何局部变量都必须声明为"final"。因此,在本例中,"local"必须声明为final,因为它的作用域和生存期在main方法中结束(因此需要更改为:final int local=1;)。

还有其他建议吗?

请参阅http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/以解释编译器如何使用final技巧来解决内部类的问题(即范围和生存期问题)。

必须使局部变量final的原因是Java将它们的值复制到内部类的实例中。在幕后发生的是,编译器生成的字节码(大致)对应于以下内容:

class ClassInMethod {
    public static void main(String[] args) {
        int local = 1;
        // this happens when you do: new Inner()
        ClassInMethod_main_Inner inner = new ClassInMethod_main_Inner();
        inner.local = local;
    }
}
// the inner class
class ClassInMethod_main_Inner {
    int local;
    public void method() {
        System.out.println(local);
    }
}

如果local不是final,并且可以在实例化Inner和调用method()之间更改其值,则对method()的调用将使用local的旧值。这可能是不正确的行为。强制使用final的原因是为了使内部类的行为更加直观。

(有些语言没有这个限制,但它需要编译器和运行时的明确支持。Java的开发人员到目前为止还没有决定致力于实现它。)

只需尝试编译即可。编译器输出:

java:11:从内部类中访问局部变量local;需要宣布为最终System.out.println(本地);^1个错误

最新更新