What finally does in Java? - Hard version


I grew up knowing that final is a keyword that when applied to variables does not make it possible to reassign the variable to something else. "If a variable is final then it's a constant" summarize many and while I'm not a fan of that definition it's probably a good way to keep the concept in mind. I just prefer to say that you cannot change the value of the variable (whatever "the value" means).

My life was happy but one day I took a deeper look at method local inner classes...

An inner class defined inside a method cannot access variables defined in the method itself. Why? Because while the class lives in the Heap and it might keep existing after the method completes (a valid reference of the class might be passed and stored somewhere else), those variables live in the stack and they die when the method returns. We don't want to have an inner class trying to access a variable that does not exist anymore at a later time because then the world will end.

Perfect. It makes sense. Excellent! And then: unless you declare those variables final..... Then your class can access them and the compiler doesn't send you to hell...

WHY??? I mean, what kind of sorcery is this? What does final exactly do and why I had to wait to talk about method local inner classes to figure this out? Assuming the final variables are stored in the Heap no matter where they are defined, are there any other applications besides the concept of making method local inner classes happy?

Quoted from "The Final word on the final keyword":

The reason for this restriction [Local classes can only reference local variables and parameters that are declared final.] becomes apparent if we shed some light on how local classes are implemented. An anonymous local class can use local variables because the compiler automatically gives the class a private instance field to hold a copy of each local variable the class uses. The compiler also adds hidden parameters to each constructor to initialize these automatically created private fields. Thus, a local class does not actually access local variables, but merely its own private copies of them. The only way this can work correctly is if the local variables are declared final, so that they are guaranteed not to change. With this guarantee in place, the local class is assured that its internal copies of the variables accurately reflect the actual local variables.