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.
Inner classes that are declared inside a method can access only the final members of that method. I am unable to understand why. The method body may create an object of this inner class and assign it to a class member variable. Therefore, any operations on the class might result in runtime exceptions when it refer to variables inside the method scope where it is declared. But how does it help to declare those members 'final'. As I know it, 'final' just means a constant. A constant declared inside a method will only have that method's scope. Any explanations, please? Thanks in advance, AJ
Well, the term "members" usually refers to variables or methods associated with a class or instance - static class members and nonstatic class members, respectively. So I must point out that an inner class is able to access any member of an enclosing class, regardless of whether it's final or not. However, it may only access a local variable (not member) if that variable is final. The reason is, what happens if you're running a multi-threaded application and you hand an inner class instance off to another thread, and then afterwards the local variable is changed by the initial thread? Should that change affect the inner class instance in the other thread? How? When? Remember that when accessing member variables, it is possible to use synchronized methods to access a vaiable safely - but there isn't really a way to guarantee the safety of local variables, because there's no associated object which can be used as a monitor for synchronization. So this issue could become quite complicated and confusing; to avoid these difficulties, the language designers decided to only allow local variable access from inner classes if the variable was final. It just makes things simpler - otherwise we'd have to have a bunch of additional rules to handle all the special cases of what could happen to the local variable in a multithreaded environment, and no one really wants that or needs it.
"I'm not back." - Bill Harding, Twister
Joined: May 07, 2001
Let me explain my question using some code:
The above code when compiled and executed works fine and prints "10". My question is what is the scope of the final variables. I would expect it to go out of scope after "out.methodA();" - i.e., after methodA() exits. But the inner class still has a reference to it. Obviously, I am not understanding the scope of the final variables correctly. Could you please explain this behavior? Thanks, AJ
Joined: Jan 30, 2000
As you've seen, the variable is still in scope inside the inner class. Scope is defined in terms of position, not events - the code for the inner class is inside the method which contains the local variable, therefore the local variable is in scope within the inner class. Always. Regardless of what events might occur, such as the method ending - if a reference to the inner class still exists, then it still has access to the local variable. The way this is accomplished is that the inner class receives a copy of the variable when it is created. So even though the original may be destroyed by the JVM when the method ends, the copy may still exist. Obviously it would be confusing if the copy ever had a different value from the original, which is another reason why the variable must be declared final.