This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
joe bob wrote:
I have a little problem here. Why the following code would fail to compile at line 8because it's not declared as final??
First of all, do you understand why the code even compiles in the first place? After all, the scope of the x and z variable is only during the method execution, while the scope for the inner instance is til it is garbage collected -- so in theory, if your method returns the instance created in the method (and the stuff in the constructor is moved to a method), then doesn't the code in the method local inner class access variables that no longer exist?
joe bob wrote:The concept is a little bit off to me, could you explain a little more ?
Simply, it is possible for instances (of method local classes) created in a method to outlive the method execution itself -- the method can return the instance, or place it somewhere such as a static variable. This means that the method local class should never be allowed to access the local variables of the method.
However, as you know, if that restriction was used, then the benefit of using method local inner classes would be arguably degraded. And the Java designers understood this too.... Anyway, what if the value of the method local variable is constant and is known? Then you can argue that the inner class is really just using the value and not the local variable directly. The java language specification states that if the method variable is final *and* it is already set at the time of the class instantiation, then the method local inner class will make a copy of the value internally.
So back to your question...
joe bob wrote:
I have a little problem here. Why the following code would fail to compile at line 8 because it's not declared as final??
The question is backwards. It should be why the following code compiles when it is declared final -- as it should never compile at all. And the answer is, it compiles because the Java Language Specification allows the method local inner class to make a copy of the variable -- but only if the value is constant and is known.
It has something to do with garbage collection and the variable scope in a method.
In KB's study guide, if a method local inner class wants to access the method's variable, that variable must be final.
Suppose this inner class has an instance and this instance is passed to other methods as argument. However, the variable that this instance encapsulated is garbage collected after the method finishes. That will be a problem.
If this variable is set to be final, then it won't be garbage collected even if the method completes. This variable can still be used by the inner class instance.