Question

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’. 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;).

Any other suggestions?

Was it helpful?

Solution

The reason why you have to make the local variables final is that Java copies their values into the instance of the inner class. 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. This would likely be incorrect behaviour. The reason final is mandated is to make the behaviour of inner classes more intuitive.

(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.)

OTHER TIPS

See http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/ for an explanation of how the compiler uses the final trick to get around problems with inner classes (i.e. scope and lifetime problems).

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top