14

Why do I need to declare a local variable as final if my Inner class defined within the method needs to use it ?

Example :

class MyOuter2 {

private String x = "Outer2";

void doStuff() {
    final String y = "Hello World";

    final class MyInner {

        String z = y;

        public void seeOuter() {
            System.out.println("Outer x is "+x);
            System.out.println("Local variable is "+y);
            MyInner mi = new MyInner();
            mi.seeOuter();
        }
    }
}

}

Why the String y needs to be a final constant ? How does it impact ?

AllTooSir
  • 48,828
  • 16
  • 130
  • 164
  • see if this discussion helps http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/ – kosa Apr 26 '12 at 17:52
  • possible duplicate of [Cannot refer to a non-final variable inside an inner class defined in a different method](http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-differen) –  Apr 26 '12 at 17:53
  • [Question about local final variable in Java](http://stackoverflow.com/questions/5947352/question-about-local-final-variable-in-java). – Lion Apr 26 '12 at 18:33

6 Answers6

17

Local variables always live on the stack, the moment method is over all local variables are gone.

But your inner class objects might be on heap even after the method is over (Say an instance variable holds on to the reference), so in that case it cannot access your local variables since they are gone, unless you mark them as final

mprabhat
  • 20,107
  • 7
  • 46
  • 63
13

The answer is the two are in different scopes. So that variable could change before the inner class accesses it. Making it final prevents that.

ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
  • 3
    This has changed in java 8: http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html#accessing-members-of-an-enclosing-class – ohcibi Mar 20 '14 at 20:38
9

It's because the inner class inside a function actually makes a copy of the local variable because local variable may be destroyed after the function call while the instance of the local class still exists. To make the two copies of the local variable always have the same value(to make them seem identical), you have to declare the variable as final.

charles_ma
  • 786
  • 7
  • 10
  • There are tens if not hundreds of explanations why this rule was put into compiler. This is the only one that both makes sense and is easily understandable. – zubergu Jun 03 '20 at 20:10
3

I think this is to prevent that the programmer would make mistakes. This way, the compiler reminds the programmer that the variable will not be accessible anymore when you leave that method. This is critical with looping. Imagine this code:

public void doStuff()
{
    InnerClass cls[] = new InnerClass[100];
    for (int i = 0; i < 100; ++i)
    {
        cls[i] = new InnerClass()
        {
            void doIt()
            {
                System.out.println(i);
            }
        };
    }
}

When the doIt() method is called, what will be printed? i changed while looping. To prevent that confusion, you have to copy the variable to a local variable or create the variable final, but then you will be unable to loop.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
1

Your inner class is final and so you shouldn't be able to modify anything from inside your final entity.

abson
  • 9,148
  • 17
  • 50
  • 69
0

According to Java memory model use of final variable guarantees that the final variable are always initialized. We get error when we try to use local variable without initialization. using final guarantees the inner class that local variable which is been used is initialized.

Vishal
  • 126
  • 1
  • 5