0

我需要解释为什么以下代码无法编译(就范围和生命周期而言):

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;)。

还有其他建议吗?

4

3 回答 3

2

有关编译器如何使用该final技巧解决内部类问题(即范围和终身问题)。

于 2012-02-05T21:17:48.943 回答
1

只是尝试编译它。编译器输出:

ClassInMethod.java:11:从内部类内部访问局部变量local;需要声明为final
    System.out.println(local);
                       ^
1 个错误
于 2012-02-05T21:15:28.820 回答
1

您必须制作局部变量的原因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时更改其值,则调用将使用. 这可能是不正确的行为。强制的原因是使内部类的行为更直观。Innermethod()method()localfinal

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

于 2012-02-05T21:22:40.860 回答