Search code examples
javac++macrosfinalanonymous-class

final in anonymous classes,just like macros in C++?


Working with anonymous innerclasses in java,you have to declare the variables of enclosing class which you are using in the anonymous innerclass as final. Ok i got it that why this must be done from

"By making lastPrice and price final, they are not really variables anymore, but constants. The compiler can then just replace the use of lastPrice and price in the anonymous class with the values of the constants (at compile time, ofcourse), and you won't have the problem with accessing non-existent variables anymore"

This made me to wander that is the final keyword working like as Macros are in C\C++.Till now, I was using final for variables in a way that whenever I will try to modify them(accidentally) I will be getting an error that You can't modify it as it is declared as final.But this replacement thing is not clear to me.

Question: According to the selected answer from the above link answerer says

This is why it doesn't work:

The variables lastPrice and price are local variables in the main() method. The object that you create with the anonymous class might last until after the main() method returns.

When the main() method returns, local variables (such as lastPrice and price) will be cleaned up from the stack, so they won't exist anymore after main() returns.

But the anonymous class object references these variables. Things would go horribly wrong if the anonymous class object tries to access the variables after they have been cleaned up.

**

Where this storage is taking place for replacement later?Who is taking care of it?final variables are just replaced by values?

**


Solution

  • No, this is not like macros in C++. The difference is that macros are evaluated at compile time and the preprocessor replace the macro with its definition.

    final variables on the other hand can be computed at run time. Once set, though, the value cannot change at a later time. This constraint is what makes it possible to use the value in an inner class.

    Let's look at an example to make this more clear:

    public void func(final int param) {
        InnerClass inner = new InnerClass() {
            public void innerFunc() {
                System.out.println(param);
            }
        }
    
        inner.innerFunc();
    }
    

    Note that param can be set at run time by passing different values to it. But each time func() is called, a new InnerClass object is created and captures the current value of param which is guaranteed to never change because it is declared as final.

    In a different situation where the variable is constant, then the compiler can replace the value at compile time. However, this isn't special for inner classes because constants are replaced at compile time no matter where they are used.

    The moral of the story is that an anonymous inner class can access any final variable whether or not it is a compile time constant or calculated at run time.