Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Are the rules regarding timing of initialization of final and non-final fields different?

 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Please consider this code:

This, understandably, prints:

value in A's m1() = null


Now, if I just add "final" keyword to A's value field. The output is :

value in A's m1() = A

I am unable to understand why? Can someone point me to any relevant rule in JLS or tutorial?
 
Wouter Oet
Saloon Keeper
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's because final fields are set at compile time and non-final fields at run-time.
Fields are initialized after the super constructor has run. Therefor when m1 runs
the field is not yet set because the super constructor has not completed yet.

See also this topic.
 
Phungsuk Wangdu
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yes right actually we cannot assign value to instance variables until all super construtors have run
 
Raju Champaklal
Ranch Hand
Posts: 521
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
what i didnt understand is how are was allowed to change the value of value in the subclass....look assume we have a final static method in superclass..then we cant redefine a new static method with the same singature as the one in the superclass....as static method cant be overridden but they are inherited...

now what is with the final instance variable? on the same grounds as the final static methods even this must be illgeal to redefine it in the subclass....

am i right?
 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wouter Oet wrote:That's because final fields are set at compile time and non-final fields at run-time.


That doesn't seem entirely true because the following code for A also prints null even though value is final.

My guess is that public final String value = "A"; is treated specially and value is basically made a compile time constant.
 
Neha Daga
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
you did not initialize the variable "value" so it gets default null value. now when you run A class constructor it gives a call to super class constructor which calls method m1 till this time subclass (class A) constructor has not been run. so, value of variable is not initialized to "A" and hence null is printed.

Raju what you say makes sense but it happens this way for variables, if you have variable with same declaration as the super class you use super keyword to access it, I hope you can recall it now.
 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Neha Daga wrote:you did not initialize the variable "value" so it gets default null value. now when you run A class constructor it gives a call to super class constructor which calls method m1 till this time subclass (class A) constructor has not been run. so, value of variable is not initialized to "A" and hence null is printed.



Thanks for your response. Please read the original post again. The question is not why it prints null, but why it does not print null when value is made final.
 
W. Joe Smith
Ranch Hand
Posts: 710
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ann Basso wrote:
Neha Daga wrote:you did not initialize the variable "value" so it gets default null value. now when you run A class constructor it gives a call to super class constructor which calls method m1 till this time subclass (class A) constructor has not been run. so, value of variable is not initialized to "A" and hence null is printed.



Thanks for your response. Please read the original post again. The question is not why it prints null, but why it does not print null when value is made final.


When it is final like so:



The value will print as 'A', because the compiler immediately knows, at compile time, what that value is since you can't change it (hence, final). However, if you do something like:



It will still print null, unless you call setA() beforeyou attempt to print it. This is because the compiler doesn't immediately see what the value of the value variable is. What if, in setA(), you assigned it a value you pull from a database? Or it is a value that is determined on a calculation that needs input from the user? All of these things would need to be determined after the program has started running.
 
Neha Daga
Ranch Hand
Posts: 504
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yes. when final variables are declared and initialised on the same line they are compile time constants but when they are initialised later after the declaration it becomes runtime matter.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic