【问题标题】:Java Scope and Lifetime (inner classes)Java Scope 和 Lifetime(内部类)
【发布时间】:2012-02-27 12:14:31
【问题描述】:

我需要解释一下为什么下面的代码会编译失败(就范围和生命周期而言):

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

还有其他建议吗?

【问题讨论】:

  • 家庭作业?你试过编译它吗? ;)
  • 它是(因此是标签;);我有。但实际上我想我想通了——如果你对我的第二次尝试感兴趣,请在大约 30 秒内查看我的帖子!
  • 此页面可能有助于解释为什么您需要将变量设为最终变量:techtracer.com/2008/04/14/…

标签: java scope inner-classes lifetime


【解决方案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,并且您可以在实例化Inner 和调用method() 之间更改其值,则对method() 的调用将使用@987654328 的旧值@。这可能是不正确的行为。强制使用final 的原因是为了让内部类的行为更加直观。

(有些语言没有此限制,但它需要编译器和运行时的明确支持。Java 的开发人员迄今尚未决定致力于实现它。)

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      ClassInMethod.java:11:从内部类内部访问局部变量local;需要声明为final System.out.println(local); ^ 1 个错误

      【讨论】:

      • 谢谢,我得到了这么多,我只是想确保我没有遗漏任何东西!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      相关资源
      最近更新 更多