简体   繁体   English

Java范围和生命周期(内部类)

[英]Java Scope and Lifetime (inner classes)

I need to explain why the following code would fail to compile (in terms of scope and lifetime): 我需要解释为什么以下代码将无法编译(就范围和生存期而言):

class ClassInMethod
{
   public static void main(String[] args)
   {
      int local = 1;

      class Inner
      {
         public void method()
         {
             System.out.println(local);
         }
      }
   }
}

I think it's because: Any local variable used but not declared in an inner class must be declared 'final'. 认为这是因为:任何在内部类中使用但未声明的局部变量都必须声明为“ final”。 Thus, in this example 'local' must be declared final because its scope and lifetime end within the main method (so needs to be changed to: final int local = 1;). 因此,在此示例中,“ local”必须声明为final,因为它的范围和生存期在main方法内(因此需要更改为:final int local = 1;)。

Any other suggestions? 还有其他建议吗?

请参阅http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/了解有关编译器如何使用final技巧来解决内部类问题的说明(例如,作用域和一生的问题)。

Just try to compile it. 只是尝试编译它。 The compiler outputs: 编译器输出:

ClassInMethod.java:11: local variable local is accessed from within inner class; needs to be declared final
    System.out.println(local);
                       ^
1 error

The reason why you have to make the local variables final is that Java copies their values into the instance of the inner class. 您必须使局部变量成为final变量的原因是Java将其值复制到内部类的实例中。 What happens behind the scenes is that the compiler generates bytecode that (roughly) corresponds to this: 幕后发生的事情是,编译器生成(大致)与此对应的字节码:

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

If local weren't final , and you could change its value between when Inner is instantiated, and when method() is called, the call to method() would use the old value of local . 如果local没有final ,你可以改变它的当值之间Inner被实例化,并在method()被调用,调用method()会使用的旧值local This would likely be incorrect behaviour. 这可能是不正确的行为。 The reason final is mandated is to make the behaviour of inner classes more intuitive. 要求final的原因是为了使内部类的行为更直观。

(There are languages that don't have this restriction, but it requires explicit support from the compiler and runtime. Java's developers have so far not decided to dedicate their effort to implementing it.) (有些语言没有此限制,但是它需要编译器和运行时的显式支持。到目前为止,Java的开发人员尚未决定致力于实现它。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM