aspose file tools*
The moose likes Beginning Java and the fly likes Why Local Variables Should Declare With Final ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Why Local Variables Should Declare With Final ?" Watch "Why Local Variables Should Declare With Final ?" New topic
Author

Why Local Variables Should Declare With Final ?

Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Hi, Please Look at this code...


Compiler says int Age must be final... I wonder why ?
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Answer these questions first:

a) What type of variable is "age"?

b) Where is variable "age" being stored i.e in which part of the memory?




~ Mansukh
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Mansukhdeep Thind wrote:Answer these questions first:

a) What type of variable is "a"?

b) Where is variable "a" being stored i.e in which part of the memory?




(a) you can declare any type of variable is called "a"

(b) if it is local variable it is stored in stack
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Correct. Now if "age" is a local method variable and is on the stack of that method, then what will happen once the method has completed its execution? What will happen to the stack?
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Mansukhdeep Thind wrote:Correct. Now if "age" is a local method instance variable and is on the stack of that method, then what will happen once the method has completed its execution? What will happen to the stack?


Thanks dear.. I got it...
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

What did you get? Can you please write it down? I just want to be sure you got the right thing. Why can't I access any local variable from a method local inner class unless it is declared as final? Why is the compiler complaining?
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Mansukhdeep Thind wrote:What did you get? Can you please write it down? I just want to be sure you got the right thing. Why can't I access any local variable from a method local inner class unless it is declared as final? Why is the compiler complaining?


I think.. I got it wrong... Ya..

Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
To your question...
Mansukhdeep Thind wrote:Correct. Now if "age" is a local method instance variable and is on the stack of that method, then what will happen once the method has completed its execution? What will happen to the stack?


once the method has completed... there is no age in stack..
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

No problem. Now answer another question. Considering the same example :



How will you create an instance of "LocalInnerClass"? Secondly, where will you do that i.e in which line?
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84

Like this...

Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Correct..
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
No... You can't
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Why? "age" is a local instance variable of the method in which my inner class is there. Right? So why can't I access it like this? Won't innerClass instance have a copy of the "age" variable? I have almost led you the answer now. Can you figure out the problem?
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
"I said no.. you can't" because


Look at line 19 , it should generate compile time error...
and honestly...
I don't know how to create instance or reference type from local inner class outside of the block, where inner class has been declared... ? (as you have done here in line 24)
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Further more, I actually don't what is called "local instance variable" ? Can you explain please ?
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

There seems to be some semantic issue with the example I was trying to put through. Will do it later for you. Anyways, the problem is that local method variables have a life only till the method stack is there. After that the "age" variable is no more present. Now since there is no "age" variable as there is no stack, the compiler will complain if I try to access that variable using inner class reference unless it is marked as final. Only then will the inner class instance get its own copy of the instance variable. The moral of the story is this::

Marking the local variable as final inside a method which has an inner class allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory. So in essence , you would be dealing with the copy of the original local variable "age".

Let me know in case you still have some doubts.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8207
    
  23

Ranjith Suranga wrote:Further more, I actually don't what is called "local instance variable" ? Can you explain please ?

I don't think there's any such animal. What you have is a local variable.

Furthermore, the specific problem you're running into can be fixed by simply writing your class just as you would any other, viz:then you can declare your local variable any way you like, because its value won't be needed outside its normal scope.

Sometimes the simplest solution is the best.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Ranjith Suranga wrote:Further more, I actually don't what is called "local instance variable" ? Can you explain please ?


I meant local variables.
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Winston Gutkowski wrote:
Ranjith Suranga wrote:Further more, I actually don't what is called "local instance variable" ? Can you explain please ?

I don't think there's any such animal. What you have is a local variable.

Furthermore, the specific problem you're running into can be fixed by simply writing your class just as you would any other, viz:then you can declare your local variable any way you like, because its value won't be needed outside its normal scope.

Sometimes the simplest solution is the best.

Winston


I wanted the lad to discover it for himself as to why we cannot access local variables from inner classes unless they are marked as final. That was his question. Your solution is simple no doubt. But it does not answer his question.
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Winston Gutkowski wrote:
Furthermore, the specific problem you're running into can be fixed by simply writing your class just as you would any other, viz:then you can declare your local variable any way you like, because its value won't be needed outside its normal scope.

Sometimes the simplest solution is the best.

Winston


How can I access "int age = 10" in Local Inner Class... ? I can't understand your solution honestly.. Could you please explain... ?
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Ranjith Suranga wrote:"I said no.. you can't" because


Look at line 19 , it should generate compile time error...
and honestly...
I don't know how to create instance or reference type from local inner class outside of the block, where inner class has been declared... ? (as you have done here in line 24)


I need to correct this example. Do not consider this..
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Mansukhdeep Thind wrote:Let me know in case you still have some doubts.


Yes dear, I still have some doubts...

Mansukhdeep Thind wrote: the compiler will complain if I try to access that variable using inner class reference unless it is marked as final. Only then will the inner class instance get its own copy of the instance variable..


Should we want to guess it or has it been specified in JLS or somewhere ?
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8207
    
  23

Ranjith Suranga wrote:How can I access "int age = 10" in Local Inner Class... ?

You're not. Maybe this will explain better. The following is precisely equivalent to what I wrote before:
Winston
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Ranjith Suranga wrote:
Mansukhdeep Thind wrote:Let me know in case you still have some doubts.


Yes dear, I still have some doubts...

Mansukhdeep Thind wrote: the compiler will complain if I try to access that variable using inner class reference unless it is marked as final. Only then will the inner class instance get its own copy of the instance variable..


Should we want to guess it or has it been specified in JLS or somewhere ?


I did not get your question. Can you re-phrase?
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8207
    
  23

Ranjith Suranga wrote:Should we want to guess it or has it been specified in JLS or somewhere ?

Never guess. It's always in the JLS.

Winston
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
In JLS, i found this..
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must be declared final.

Any local variable used but not declared in an inner class must be definitely assigned (ยง16) before the body of the inner class.


Even though, it has been specified there, It does not answer the question "Why ? "
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Mansukhdeep Thind wrote:

I did not get your question. Can you re-phrase?


I mean your explanation, It feels really OK and I found something similar to like your explanation also here...

http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/

But, I want to know is, How can I know this.. I mean it should be specified in somewhere ?

I could not able to find it in JLS also...
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8207
    
  23

Mansukhdeep Thind wrote:I wanted the lad to discover it for himself as to why we cannot access local variables from inner classes unless they are marked as final. That was his question.

True.

Your solution is simple no doubt. But it does not answer his question.

No, I was simply providing an alternative. Personally, I think referencing variables outside their scope is a bad habit; and to be honest I wish Java had never allowed it. If you want to create an object with an initialized value, do it the normal way.

That said, you're quite correct.

Winston
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Mansukhdeep Thind wrote:
Marking the local variable as final inside a method which has an inner class allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory.


Where this has been specified... ? can you tell me... please ?
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Ranjith Suranga wrote:
Mansukhdeep Thind wrote:

I did not get your question. Can you re-phrase?


I mean your explanation, It feels really OK and I found something similar to like your explanation also here...

http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/

But, I want to know is, How can I know this.. I mean it should be specified in somewhere ?

I could not able to find it in JLS also...


Ok. Its 1:30 a.m IST. I will make this my last post and go to sleep. To answer your question, I shall explain how the JVM treats inner classes. Lets consider the example that you started with:



Now when the JVM compiles these classes, it will generate 2 separate class files. Yes. 2 separate class files. One will be called Outer.class and the other will be called Outer$LocalInnerClass.class. Now there is no way that methods of one class file can know about local variables of other class file. Or is there. "final" keyword to the rescue. It ensures that during compilation, if you mark a local variable as final, then when the inner class is being compiled, that variable will also be sent as a separate copy like in this case val$age. Otherwise, the separate inner class file does not know at compile time what age is. So how will you use it? Got it?
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Ranjith Suranga wrote:
Mansukhdeep Thind wrote:
Marking the local variable as final inside a method which has an inner class allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory.


Where this has been specified... ? can you tell me... please ?


Here you go.. final keyword in java Read under the heading "Final and inner classes".
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3018
    
  10
No, he's asking about the specification. Try this, from JLS 8.1.3:
Any local variable, formal parameter, or exception parameter used but not declared in an inner class must be declared final.
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

Mike Simmons wrote:No, he's asking about the specification. Try this, from JLS 8.1.3:
Any local variable, formal parameter, or exception parameter used but not declared in an inner class must be declared final.


He found that himself already. But his question now is why it is that local variables, formal parameters , exception parameters should be marked final? Hence, I explained how the JVM treats an inner class and its enclosing outer class while compilation..
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3018
    
  10
OK. Then I would ask Ranjith: why should the explanation need to be specified anywhere? That's not the job of a specification. They may choose to explain, but they don't have to.

Another way to look is: Java's creators certainly could have specified this differently. Other languages allow similar references by implicitly creating closures, constructs to capture the state of local variables and pass them outside their original lexical scope. Java's designers simply chose not to do this, probably because they felt is would be too complicated. Even now, with Java 8 approaching with the inclusion of lambdas, which are concise local function declarations for purposes similar to anonymous functions, they still do not plan to allow lambdas to access nonfinal local variables. Maybe they will in the future. But don't count on it. At some opoint, we sometimes have to accept that some things are the way they are because the people who created the language chose to make it that way.
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
OK... I finally understand it practically though I can't find a proper reference for specification of that...

What I did is,

(1) I have downloaded a java Decompiler from here...
http://www.varaneckas.com/jad/

(2) I wrote this code and then compiled..

After compilation has been done, it has generate two class files which are
(I)Outer.class
(II)Outer$1LocalInnerClass.class

(3). I copied JAD.exe(which I have downloaded) into the same folder where class files have been located...

(4). Then I Opened the command prompt, moved to the folder where class files are.. and executed this below command at the command prompt...
jad Outer$1LocalInnerClass.class

(5). It had created a Outer$1LocalInnerClass.jad file in the same directory where class files were, I opened it by using NOTEPAD

(6). I found this..



(7). I changed my source code again little bit to like this to see what happens...



(8). I repeated all steps again for decompiler process...

(9). Then I found code something like this...


(10). Now,
Any local variable, formal parameter, or exception parameter used but not declared
in an inner class must be declared final.


I understand, "why..?" finally...

It is extremely thank you for all the guys who has helped me by giving your answers and opinions..
and really sorry about your sleep, Mansukhdeep Thind..

Once again.. thank you for your help..
Even though, I could not able to find a specification for this, at least I have known it now practically...
Ranji Sura
Ranch Hand

Joined: Oct 28, 2012
Posts: 84
Mike Simmons wrote:OK. Then I would ask Ranjith: why should the explanation need to be specified anywhere? That's not the job of a specification. They may choose to explain, but they don't have to.

Another way to look is: Java's creators certainly could have specified this differently. Other languages allow similar references by implicitly creating closures, constructs to capture the state of local variables and pass them outside their original lexical scope. Java's designers simply chose not to do this, probably because they felt is would be too complicated. Even now, with Java 8 approaching with the inclusion of lambdas, which are concise local function declarations for purposes similar to anonymous functions, they still do not plan to allow lambdas to access nonfinal local variables. Maybe they will in the future. But don't count on it. At some opoint, we sometimes have to accept that some things are the way they are because the people who created the language chose to make it that way.


Ya, you are quite right. may be.. I thought too much about that...
Sorry for that...
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

No problem buddy. The important thing is that one should understand not only the "what happens when" part but more importantly "why it happens so".. You are welcome anytime.
Ishan Pandya
Ranch Hand

Joined: Feb 06, 2012
Posts: 223

Hie ranjit. After a really long discussion on this i would like to add that final variables may be stored as a special part of the heap called the "permanent generation".
Try reading this discussion on where the final variables are stored. You will gets some more idea.
And try searching permanent generation on this link.

Hope it helps.


OCPJP
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39828
    
  28
Ishan Pandya wrote: . . . that final variables may be stored as a special part of the heap called the "permanent generation". . . .
Local variables on the heap? Local variables live on the stack, but they may be pointers to objects on the heap.
Ishan Pandya
Ranch Hand

Joined: Feb 06, 2012
Posts: 223

Campbell Ritchie wrote:Local variables on the heap? Local variables live on the stack, but they may be pointers to objects on the heap.


So is there any other reason as why they are used inside local Inner class??
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why Local Variables Should Declare With Final ?